Protocols: Move __THROW__ macro to MMSException header file
[remote/remote-mci.git] / mcs / FileDescriptor.cc
blobdfee645fb563970a0181fec8c4c0244e00d35eaf
1 #include "FileDescriptor.h"
2 #include "macros.h"
4 namespace remote { namespace mcs {
6 bool FileDescriptor::serviceLoop()
8 unsigned int i, instanceCount;
9 int f;
10 filedescriptorsbyfd_t::iterator fileDescriptorIterator;
11 // register the timeout handler
12 signal( SIGALRM, timeoutHandler );
13 installSignalHandlers();
17 instanceCount = instances.size();
18 pollfd fdmap[instanceCount];
19 FileDescriptor::buildPollMap(fdmap);
21 if ( poll(fdmap,instanceCount,-1) < 0)
23 if (errno == EINTR)
24 continue;
25 __THROW__("Error in poll!");
28 try
30 // look for activity on any sockets
31 for ( i = 0; i < instanceCount; i++ )
33 if ( fdmap[i].revents )
35 f = fdmap[i].fd;
36 fileDescriptorIterator = instances.find(f);
37 if (fileDescriptorIterator != instances.end())
39 fileDescriptorIterator->second->handleEvent(fdmap[i].revents);
44 catch (remote::protocols::MMSException e)
46 clearTimeout();
47 log("Exception: %s\n",e.what());
48 fileDescriptorIterator->second->clearTimeout();
49 fileDescriptorIterator->second->destroy(false);
52 while (!exitSignal);
54 return exitSignal == 0;
57 FileDescriptor::FileDescriptor(int p_fd)
59 clearTimeout();
60 fd = p_fd;
61 log("Opened fd %i\n",fd);
62 instances[fd] = this;
65 void FileDescriptor::buildPollMap(pollfd* map)
67 int j = 0;
68 filedescriptorsbyfd_t::iterator i;
69 for (i = instances.begin(); i != instances.end(); i++)
71 map[j].fd = i->second->fd;
72 map[j].events = POLLMSG|POLLRDBAND|POLLRDNORM|POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL;
73 map[j].revents = 0;
74 j++;
79 FileDescriptor::~FileDescriptor()
81 if (close(fd) != 0)
82 log("close(%i) - %s\n", fd, strerror(errno));
83 else
84 log("Closed fd %i\n", fd);
85 instances.erase(fd);
88 void FileDescriptor::destroy(bool silent)
90 delete this;
94 void FileDescriptor::setTimeout(int secs)
96 itimerval timeout;
97 // stop the timer
98 timeout.it_interval.tv_sec = 0;
99 timeout.it_interval.tv_usec = 0;
100 timeout.it_value.tv_sec = secs;
101 timeout.it_value.tv_usec = 0;
102 if (setitimer(ITIMER_REAL, &timeout, NULL))
104 __THROW__ ("Timer set error\n");
106 currentFd = fd;
109 void FileDescriptor::clearTimeout()
111 itimerval timeout;
112 // stop the timer
113 timeout.it_interval.tv_sec = 0;
114 timeout.it_interval.tv_usec = 0;
115 timeout.it_value.tv_sec = 0;
116 timeout.it_value.tv_usec = 0;
117 if (setitimer(ITIMER_REAL, &timeout, NULL))
119 __THROW__ ("Timer clear error\n");
121 currentFd = -1;
125 RETSIGTYPE FileDescriptor::timeoutHandler(int sig)
127 log( "Timeout occured!\n");
128 close(currentFd); // this should generate an exception
131 void FileDescriptor::exitSignalHandler(int signo)
133 exitSignal = signo;
136 void FileDescriptor::installSignalHandlers()
138 struct sigaction act;
140 memset(&act, 0, sizeof(act));
141 act.sa_handler = SIG_IGN;
142 act.sa_flags = 0;
144 sigaction(SIGPIPE, &act, NULL);
146 memset(&act, 0, sizeof(act));
147 act.sa_handler = exitSignalHandler;
148 sigfillset(&act.sa_mask);
149 sigaction(SIGINT, &act, NULL);
150 sigaction(SIGTERM, &act, NULL);
151 sigaction(SIGSEGV, &act, NULL);
152 sigaction(SIGKILL, &act, NULL);
156 filedescriptorsbyfd_t FileDescriptor::instances;
157 int FileDescriptor::currentFd = -1;
158 int FileDescriptor::exitSignal = 0;