00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __DBUSXX_DISPATCHER_H
00026 #define __DBUSXX_DISPATCHER_H
00027
00028 #include "api.h"
00029 #include "connection.h"
00030 #include "eventloop.h"
00031
00032 namespace DBus
00033 {
00034
00035 class DXXAPI Timeout
00036 {
00037 public:
00038
00039 class Internal;
00040
00041 Timeout(Internal *i);
00042
00043 virtual ~Timeout() {}
00044
00057 int interval() const;
00058
00059 bool enabled() const;
00060
00073 bool handle();
00074
00075 virtual void toggle() = 0;
00076
00077 private:
00078
00079 DXXAPILOCAL Timeout(const Timeout &);
00080
00081 private:
00082
00083 Internal *_int;
00084 };
00085
00086 class DXXAPI Watch
00087 {
00088 public:
00089
00090 class Internal;
00091
00092 Watch(Internal *i);
00093
00094 virtual ~Watch() {}
00095
00104 int descriptor() const;
00105
00116 int flags() const;
00117
00118 bool enabled() const;
00119
00138 bool handle(int flags);
00139
00140 virtual void toggle() = 0;
00141
00142 private:
00143
00144 DXXAPILOCAL Watch(const Watch &);
00145
00146 private:
00147
00148 Internal *_int;
00149 };
00150
00151 class DXXAPI Dispatcher
00152 {
00153 public:
00154
00155 virtual ~Dispatcher()
00156 {}
00157
00158 void queue_connection(Connection::Private *);
00159
00160 void dispatch_pending();
00161 bool has_something_to_dispatch();
00162
00163 virtual void enter() = 0;
00164
00165 virtual void leave() = 0;
00166
00167 virtual Timeout *add_timeout(Timeout::Internal *) = 0;
00168
00169 virtual void rem_timeout(Timeout *) = 0;
00170
00171 virtual Watch *add_watch(Watch::Internal *) = 0;
00172
00173 virtual void rem_watch(Watch *) = 0;
00174
00175 struct Private;
00176
00177 private:
00178 void dispatch_pending(Connection::PrivatePList &pending_queue);
00179
00180 DefaultMutex _mutex_p;
00181 DefaultMutex _mutex_p_copy;
00182
00183 Connection::PrivatePList _pending_queue;
00184 };
00185
00186 extern DXXAPI Dispatcher *default_dispatcher;
00187
00188
00189
00190
00191 class DXXAPI Mutex
00192 {
00193 public:
00194
00195 virtual ~Mutex() {}
00196
00197 virtual void lock() = 0;
00198
00199 virtual void unlock() = 0;
00200
00201 struct Internal;
00202
00203 protected:
00204
00205 Internal *_int;
00206 };
00207
00208 class DXXAPI CondVar
00209 {
00210 public:
00211
00212 virtual ~CondVar() {}
00213
00214 virtual void wait(Mutex *) = 0;
00215
00216 virtual bool wait_timeout(Mutex *, int timeout) = 0;
00217
00218 virtual void wake_one() = 0;
00219
00220 virtual void wake_all() = 0;
00221
00222 struct Internal;
00223
00224 protected:
00225
00226 Internal *_int;
00227 };
00228
00229 typedef Mutex *(*MutexNewFn)();
00230 typedef void (*MutexUnlockFn)(Mutex *mx);
00231
00232 #ifndef DBUS_HAS_RECURSIVE_MUTEX
00233 typedef bool (*MutexFreeFn)(Mutex *mx);
00234 typedef bool (*MutexLockFn)(Mutex *mx);
00235 #else
00236 typedef void (*MutexFreeFn)(Mutex *mx);
00237 typedef void (*MutexLockFn)(Mutex *mx);
00238 #endif//DBUS_HAS_RECURSIVE_MUTEX
00239
00240 typedef CondVar *(*CondVarNewFn)();
00241 typedef void (*CondVarFreeFn)(CondVar *cv);
00242 typedef void (*CondVarWaitFn)(CondVar *cv, Mutex *mx);
00243 typedef bool (*CondVarWaitTimeoutFn)(CondVar *cv, Mutex *mx, int timeout);
00244 typedef void (*CondVarWakeOneFn)(CondVar *cv);
00245 typedef void (*CondVarWakeAllFn)(CondVar *cv);
00246
00247 void DXXAPI _init_threading();
00248
00249 void DXXAPI _init_threading(
00250 MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn,
00251 CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn
00252 );
00253
00254 template<class Mx, class Cv>
00255 struct Threading
00256 {
00257 static void init()
00258 {
00259 _init_threading(
00260 mutex_new, mutex_free, mutex_lock, mutex_unlock,
00261 condvar_new, condvar_free, condvar_wait, condvar_wait_timeout, condvar_wake_one, condvar_wake_all
00262 );
00263 }
00264
00265 static Mutex *mutex_new()
00266 {
00267 return new Mx;
00268 }
00269
00270 static void mutex_free(Mutex *mx)
00271 {
00272 delete mx;
00273 }
00274
00275 static void mutex_lock(Mutex *mx)
00276 {
00277 mx->lock();
00278 }
00279
00280 static void mutex_unlock(Mutex *mx)
00281 {
00282 mx->unlock();
00283 }
00284
00285 static CondVar *condvar_new()
00286 {
00287 return new Cv;
00288 }
00289
00290 static void condvar_free(CondVar *cv)
00291 {
00292 delete cv;
00293 }
00294
00295 static void condvar_wait(CondVar *cv, Mutex *mx)
00296 {
00297 cv->wait(mx);
00298 }
00299
00300 static bool condvar_wait_timeout(CondVar *cv, Mutex *mx, int timeout)
00301 {
00302 return cv->wait_timeout(mx, timeout);
00303 }
00304
00305 static void condvar_wake_one(CondVar *cv)
00306 {
00307 cv->wake_one();
00308 }
00309
00310 static void condvar_wake_all(CondVar *cv)
00311 {
00312 cv->wake_all();
00313 }
00314 };
00315
00316 }
00317
00318 #endif//__DBUSXX_DISPATCHER_H