00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <dbus-c++/eventloop.h>
00029 #include <dbus-c++/debug.h>
00030
00031 #include <sys/poll.h>
00032 #include <sys/time.h>
00033
00034 #include <dbus/dbus.h>
00035
00036 using namespace DBus;
00037 using namespace std;
00038
00039 static double millis(timeval tv)
00040 {
00041 return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
00042 }
00043
00044 DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
00045 : _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
00046 {
00047 timeval now;
00048 gettimeofday(&now, NULL);
00049
00050 _expiration = millis(now) + interval;
00051
00052 _disp->_mutex_t.lock();
00053 _disp->_timeouts.push_back(this);
00054 _disp->_mutex_t.unlock();
00055 }
00056
00057 DefaultTimeout::~DefaultTimeout()
00058 {
00059 _disp->_mutex_t.lock();
00060 _disp->_timeouts.remove(this);
00061 _disp->_mutex_t.unlock();
00062 }
00063
00064 DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
00065 : _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
00066 {
00067 _disp->_mutex_w.lock();
00068 _disp->_watches.push_back(this);
00069 _disp->_mutex_w.unlock();
00070 }
00071
00072 DefaultWatch::~DefaultWatch()
00073 {
00074 _disp->_mutex_w.lock();
00075 _disp->_watches.remove(this);
00076 _disp->_mutex_w.unlock();
00077 }
00078
00079 DefaultMutex::DefaultMutex()
00080 {
00081 pthread_mutex_init(&_mutex, NULL);
00082 }
00083
00084 DefaultMutex::DefaultMutex(bool recursive)
00085 {
00086 if (recursive)
00087 {
00088 pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
00089 _mutex = recmutex;
00090 }
00091 else
00092 {
00093 pthread_mutex_init(&_mutex, NULL);
00094 }
00095 }
00096
00097 DefaultMutex::~DefaultMutex()
00098 {
00099 pthread_mutex_destroy(&_mutex);
00100 }
00101
00102 void DefaultMutex::lock()
00103 {
00104 pthread_mutex_lock(&_mutex);
00105 }
00106
00107 void DefaultMutex::unlock()
00108 {
00109 pthread_mutex_unlock(&_mutex);
00110 }
00111
00112 DefaultMainLoop::DefaultMainLoop() :
00113 _mutex_w(true)
00114 {
00115 }
00116
00117 DefaultMainLoop::~DefaultMainLoop()
00118 {
00119 _mutex_w.lock();
00120
00121 DefaultWatches::iterator wi = _watches.begin();
00122 while (wi != _watches.end())
00123 {
00124 DefaultWatches::iterator wmp = wi;
00125 ++wmp;
00126 _mutex_w.unlock();
00127 delete(*wi);
00128 _mutex_w.lock();
00129 wi = wmp;
00130 }
00131 _mutex_w.unlock();
00132
00133 _mutex_t.lock();
00134
00135 DefaultTimeouts::iterator ti = _timeouts.begin();
00136 while (ti != _timeouts.end())
00137 {
00138 DefaultTimeouts::iterator tmp = ti;
00139 ++tmp;
00140 _mutex_t.unlock();
00141 delete(*ti);
00142 _mutex_t.lock();
00143 ti = tmp;
00144 }
00145 _mutex_t.unlock();
00146 }
00147
00148 void DefaultMainLoop::dispatch()
00149 {
00150 _mutex_w.lock();
00151
00152 int nfd = _watches.size();
00153
00154 if (_fdunlock)
00155 {
00156 nfd = nfd + 2;
00157 }
00158
00159 pollfd fds[nfd];
00160
00161 DefaultWatches::iterator wi = _watches.begin();
00162
00163 for (nfd = 0; wi != _watches.end(); ++wi)
00164 {
00165 if ((*wi)->enabled())
00166 {
00167 fds[nfd].fd = (*wi)->descriptor();
00168 fds[nfd].events = (*wi)->flags();
00169 fds[nfd].revents = 0;
00170
00171 ++nfd;
00172 }
00173 }
00174
00175 if (_fdunlock)
00176 {
00177 fds[nfd].fd = _fdunlock[0];
00178 fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
00179 fds[nfd].revents = 0;
00180
00181 nfd++;
00182 fds[nfd].fd = _fdunlock[1];
00183 fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
00184 fds[nfd].revents = 0;
00185 }
00186
00187 _mutex_w.unlock();
00188
00189 int wait_min = 10000;
00190
00191 DefaultTimeouts::iterator ti;
00192
00193 _mutex_t.lock();
00194
00195 for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
00196 {
00197 if ((*ti)->enabled() && (*ti)->interval() < wait_min)
00198 wait_min = (*ti)->interval();
00199 }
00200
00201 _mutex_t.unlock();
00202
00203 poll(fds, nfd, wait_min);
00204
00205 timeval now;
00206 gettimeofday(&now, NULL);
00207
00208 double now_millis = millis(now);
00209
00210 _mutex_t.lock();
00211
00212 ti = _timeouts.begin();
00213
00214 while (ti != _timeouts.end())
00215 {
00216 DefaultTimeouts::iterator tmp = ti;
00217 ++tmp;
00218
00219 if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
00220 {
00221 (*ti)->expired(*(*ti));
00222
00223 if ((*ti)->_repeat)
00224 {
00225 (*ti)->_expiration = now_millis + (*ti)->_interval;
00226 }
00227
00228 }
00229
00230 ti = tmp;
00231 }
00232
00233 _mutex_t.unlock();
00234
00235 _mutex_w.lock();
00236
00237 for (int j = 0; j < nfd; ++j)
00238 {
00239 DefaultWatches::iterator wi;
00240
00241 for (wi = _watches.begin(); wi != _watches.end();)
00242 {
00243 DefaultWatches::iterator tmp = wi;
00244 ++tmp;
00245
00246 if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
00247 {
00248 if (fds[j].revents)
00249 {
00250 (*wi)->_state = fds[j].revents;
00251
00252 (*wi)->ready(*(*wi));
00253
00254 fds[j].revents = 0;
00255 }
00256 }
00257
00258 wi = tmp;
00259 }
00260 }
00261 _mutex_w.unlock();
00262 }
00263