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++/error.h>
00030 #include <dbus-c++/debug.h>
00031
00032 #include <sys/poll.h>
00033 #include <sys/time.h>
00034
00035 #include <dbus/dbus.h>
00036
00037 using namespace DBus;
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 class DefaultMutex::Attr
00080 {
00081 public:
00082 Attr();
00083
00084 Attr(int type);
00085
00086 ~Attr();
00087
00088 void set_type(int type);
00089
00090 int get_type();
00091
00092 private:
00093 void init();
00094
00095 pthread_mutexattr_t _attr;
00096
00097 friend class DefaultMutex;
00098 };
00099
00100 DefaultMutex::Attr::Attr()
00101 {
00102 init();
00103 }
00104
00105 DefaultMutex::Attr::Attr(int type)
00106 {
00107 init();
00108 set_type(type);
00109 }
00110
00111 DefaultMutex::Attr::~Attr()
00112 {
00113 pthread_mutexattr_destroy(&_attr);
00114 }
00115
00116 void DefaultMutex::Attr::init()
00117 {
00118 if(pthread_mutexattr_init(&_attr) != 0)
00119 throw ErrorFailed("mutex attribute initialization failed");
00120 }
00121
00122 void DefaultMutex::Attr::set_type(int type)
00123 {
00124 if(pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE) != 0)
00125 throw ErrorFailed("mutex attribute set type failed");
00126 }
00127
00128 int DefaultMutex::Attr::get_type()
00129 {
00130 int type;
00131
00132 if(pthread_mutexattr_gettype(&_attr, &type) != 0)
00133 throw ErrorFailed("mutex attribute get type failed");
00134
00135 return type;
00136 }
00137
00138 DefaultMutex::DefaultMutex()
00139 {
00140 Attr attr(PTHREAD_MUTEX_RECURSIVE);
00141
00142 if(pthread_mutex_init(&_mutex, &attr._attr) != 0)
00143 throw ErrorFailed("mutex initialization failed");
00144 }
00145
00146 DefaultMutex::~DefaultMutex()
00147 {
00148 pthread_mutex_destroy(&_mutex);
00149 }
00150
00151 void DefaultMutex::lock()
00152 {
00153 if(pthread_mutex_lock(&_mutex) != 0)
00154 throw ErrorFailed("mutex lock failed");
00155 }
00156
00157 void DefaultMutex::unlock()
00158 {
00159 if(pthread_mutex_unlock(&_mutex) != 0)
00160 throw ErrorFailed("mutex unlock failed");
00161 }
00162
00163 DefaultMainLoop::DefaultMainLoop()
00164 {
00165 }
00166
00167 DefaultMainLoop::~DefaultMainLoop()
00168 {
00169 _mutex_w.lock();
00170
00171 DefaultWatches::iterator wi = _watches.begin();
00172 while (wi != _watches.end())
00173 {
00174 DefaultWatches::iterator wmp = wi;
00175 ++wmp;
00176 _mutex_w.unlock();
00177 delete (*wi);
00178 _mutex_w.lock();
00179 wi = wmp;
00180 }
00181 _mutex_w.unlock();
00182
00183 _mutex_t.lock();
00184
00185 DefaultTimeouts::iterator ti = _timeouts.begin();
00186 while (ti != _timeouts.end())
00187 {
00188 DefaultTimeouts::iterator tmp = ti;
00189 ++tmp;
00190 _mutex_t.unlock();
00191 delete (*ti);
00192 _mutex_t.lock();
00193 ti = tmp;
00194 }
00195 _mutex_t.unlock();
00196 }
00197
00198 void DefaultMainLoop::dispatch()
00199 {
00200 _mutex_w.lock();
00201
00202 int nfd = _watches.size();
00203
00204 pollfd fds[nfd];
00205
00206 DefaultWatches::iterator wi = _watches.begin();
00207
00208 for (nfd = 0; wi != _watches.end(); ++wi)
00209 {
00210 if ((*wi)->enabled())
00211 {
00212 fds[nfd].fd = (*wi)->descriptor();
00213 fds[nfd].events = (*wi)->flags();
00214 fds[nfd].revents = 0;
00215
00216 ++nfd;
00217 }
00218 }
00219 _mutex_w.unlock();
00220
00221 int wait_min = 10000;
00222
00223 DefaultTimeouts::iterator ti;
00224
00225 _mutex_t.lock();
00226
00227 for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
00228 {
00229 if ((*ti)->enabled() && (*ti)->interval() < wait_min)
00230 wait_min = (*ti)->interval();
00231 }
00232
00233 _mutex_t.unlock();
00234
00235 poll(fds, nfd, wait_min);
00236
00237 timeval now;
00238 gettimeofday(&now, NULL);
00239
00240 double now_millis = millis(now);
00241
00242 _mutex_t.lock();
00243
00244 ti = _timeouts.begin();
00245
00246 while (ti != _timeouts.end())
00247 {
00248 DefaultTimeouts::iterator tmp = ti;
00249 ++tmp;
00250
00251 if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
00252 {
00253 (*ti)->expired(*(*ti));
00254
00255 if ((*ti)->_repeat)
00256 {
00257 (*ti)->_expiration = now_millis + (*ti)->_interval;
00258 }
00259
00260 }
00261
00262 ti = tmp;
00263 }
00264
00265 _mutex_t.unlock();
00266
00267 _mutex_w.lock();
00268
00269 for (int j = 0; j < nfd; ++j)
00270 {
00271 DefaultWatches::iterator wi;
00272
00273 for (wi = _watches.begin(); wi != _watches.end();)
00274 {
00275 DefaultWatches::iterator tmp = wi;
00276 ++tmp;
00277
00278 if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
00279 {
00280 if (fds[j].revents)
00281 {
00282 (*wi)->_state = fds[j].revents;
00283
00284 (*wi)->ready(*(*wi));
00285
00286 fds[j].revents = 0;
00287 }
00288 }
00289
00290 wi = tmp;
00291 }
00292 }
00293 _mutex_w.unlock();
00294 }
00295