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++/dispatcher.h>
00029
00030 #include <dbus/dbus.h>
00031
00032 #include "dispatcher_p.h"
00033 #include "server_p.h"
00034 #include "connection_p.h"
00035 #include "systemerror.h"
00036
00037 DBus::Dispatcher *DBus::default_dispatcher = NULL;
00038
00039 using namespace DBus;
00040
00041 Timeout::Timeout(Timeout::Internal *i)
00042 : _int(i)
00043 {
00044 dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
00045 }
00046
00047 int Timeout::interval() const
00048 {
00049 return dbus_timeout_get_interval((DBusTimeout *)_int);
00050 }
00051
00052 bool Timeout::enabled() const
00053 {
00054 return dbus_timeout_get_enabled((DBusTimeout *)_int);
00055 }
00056
00057 bool Timeout::handle()
00058 {
00059 return dbus_timeout_handle((DBusTimeout *)_int);
00060 }
00061
00062
00063
00064
00065 Watch::Watch(Watch::Internal *i)
00066 : _int(i)
00067 {
00068 dbus_watch_set_data((DBusWatch *)i, this, NULL);
00069 }
00070
00071 int Watch::descriptor() const
00072 {
00073 #if HAVE_WIN32
00074 return dbus_watch_get_socket((DBusWatch*)_int);
00075 #else
00076 return dbus_watch_get_unix_fd((DBusWatch*)_int);
00077 #endif
00078 }
00079
00080 int Watch::flags() const
00081 {
00082 return dbus_watch_get_flags((DBusWatch *)_int);
00083 }
00084
00085 bool Watch::enabled() const
00086 {
00087 return dbus_watch_get_enabled((DBusWatch *)_int);
00088 }
00089
00090 bool Watch::handle(int flags)
00091 {
00092 return dbus_watch_handle((DBusWatch *)_int, flags);
00093 }
00094
00095
00096
00097
00098 dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
00099 {
00100 Dispatcher *d = static_cast<Dispatcher *>(data);
00101
00102 Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
00103
00104 d->add_watch(w);
00105
00106 return true;
00107 }
00108
00109 void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
00110 {
00111 Dispatcher *d = static_cast<Dispatcher *>(data);
00112
00113 Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
00114
00115 d->rem_watch(w);
00116 }
00117
00118 void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
00119 {
00120 Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
00121
00122 w->toggle();
00123 }
00124
00125 dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
00126 {
00127 Dispatcher *d = static_cast<Dispatcher *>(data);
00128
00129 Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
00130
00131 d->add_timeout(t);
00132
00133 return true;
00134 }
00135
00136 void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
00137 {
00138 Dispatcher *d = static_cast<Dispatcher *>(data);
00139
00140 Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
00141
00142 d->rem_timeout(t);
00143 }
00144
00145 void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
00146 {
00147 Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
00148
00149 t->toggle();
00150 }
00151
00152 void Dispatcher::queue_connection(Connection::Private *cp)
00153 {
00154 _mutex_p.lock();
00155 _pending_queue.push_back(cp);
00156 _mutex_p.unlock();
00157 }
00158
00159
00160 bool Dispatcher::has_something_to_dispatch()
00161 {
00162 _mutex_p.lock();
00163 bool has_something = false;
00164 for(Connection::PrivatePList::iterator it = _pending_queue.begin();
00165 it != _pending_queue.end() && !has_something;
00166 ++it)
00167 {
00168 has_something = (*it)->has_something_to_dispatch();
00169 }
00170
00171 _mutex_p.unlock();
00172 return has_something;
00173 }
00174
00175
00176 void Dispatcher::dispatch_pending()
00177 {
00178 _mutex_p.lock();
00179
00180
00181
00182 while (_pending_queue.size() > 0)
00183 {
00184 Connection::PrivatePList::iterator i;
00185
00186 i = _pending_queue.begin();
00187
00188 while (i != _pending_queue.end())
00189 {
00190 Connection::PrivatePList::iterator j = i++;
00191
00192 try {
00193 if ((*j)->do_dispatch())
00194 _pending_queue.erase(j);
00195 }
00196 catch (ConnectionTerminatedError)
00197 {
00198 while(i != _pending_queue.end() && *j == *i)
00199 ++i;
00200 _pending_queue.remove(*j);
00201 }
00202 }
00203 }
00204 _mutex_p.unlock();
00205 }
00206
00207 void DBus::_init_threading()
00208 {
00209 #ifdef DBUS_HAS_THREADS_INIT_DEFAULT
00210 dbus_threads_init_default();
00211 #else
00212 debug_log("Thread support is not enabled! Your D-Bus version is too old!");
00213 #endif//DBUS_HAS_THREADS_INIT_DEFAULT
00214 }
00215
00216 void DBus::_init_threading(
00217 MutexNewFn m1,
00218 MutexFreeFn m2,
00219 MutexLockFn m3,
00220 MutexUnlockFn m4,
00221 CondVarNewFn c1,
00222 CondVarFreeFn c2,
00223 CondVarWaitFn c3,
00224 CondVarWaitTimeoutFn c4,
00225 CondVarWakeOneFn c5,
00226 CondVarWakeAllFn c6
00227 )
00228 {
00229 #ifndef DBUS_HAS_RECURSIVE_MUTEX
00230 DBusThreadFunctions functions = {
00231 DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
00232 DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
00233 DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
00234 DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
00235 DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
00236 DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
00237 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
00238 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
00239 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
00240 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
00241 (DBusMutexNewFunction) m1,
00242 (DBusMutexFreeFunction) m2,
00243 (DBusMutexLockFunction) m3,
00244 (DBusMutexUnlockFunction) m4,
00245 (DBusCondVarNewFunction) c1,
00246 (DBusCondVarFreeFunction) c2,
00247 (DBusCondVarWaitFunction) c3,
00248 (DBusCondVarWaitTimeoutFunction) c4,
00249 (DBusCondVarWakeOneFunction) c5,
00250 (DBusCondVarWakeAllFunction) c6
00251 };
00252 #else
00253 DBusThreadFunctions functions = {
00254 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
00255 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
00256 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
00257 DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
00258 DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
00259 DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
00260 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
00261 DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
00262 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
00263 DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
00264 0, 0, 0, 0,
00265 (DBusCondVarNewFunction) c1,
00266 (DBusCondVarFreeFunction) c2,
00267 (DBusCondVarWaitFunction) c3,
00268 (DBusCondVarWaitTimeoutFunction) c4,
00269 (DBusCondVarWakeOneFunction) c5,
00270 (DBusCondVarWakeAllFunction) c6,
00271 (DBusRecursiveMutexNewFunction) m1,
00272 (DBusRecursiveMutexFreeFunction) m2,
00273 (DBusRecursiveMutexLockFunction) m3,
00274 (DBusRecursiveMutexUnlockFunction) m4
00275 };
00276 #endif//DBUS_HAS_RECURSIVE_MUTEX
00277 dbus_threads_init(&functions);
00278 }