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-integration.h>
00029 #include <dbus-c++/debug.h>
00030
00031 #include <sys/poll.h>
00032
00033 #include <dbus/dbus.h>
00034
00035 using namespace DBus;
00036
00037 BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
00038 : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
00039 {
00040 DefaultTimeout::enabled(Timeout::enabled());
00041 }
00042
00043 void BusTimeout::toggle()
00044 {
00045 debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
00046
00047 DefaultTimeout::enabled(Timeout::enabled());
00048 }
00049
00050 BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
00051 : Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
00052 {
00053 int flags = POLLHUP | POLLERR;
00054
00055 if (Watch::flags() & DBUS_WATCH_READABLE)
00056 flags |= POLLIN;
00057 if (Watch::flags() & DBUS_WATCH_WRITABLE)
00058 flags |= POLLOUT;
00059
00060 DefaultWatch::flags(flags);
00061 DefaultWatch::enabled(Watch::enabled());
00062 }
00063
00064 void BusWatch::toggle()
00065 {
00066 debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
00067
00068 DefaultWatch::enabled(Watch::enabled());
00069 }
00070
00071 void BusDispatcher::enter()
00072 {
00073 debug_log("entering dispatcher %p", this);
00074
00075 _running = true;
00076
00077 while (_running)
00078 {
00079 do_iteration();
00080 }
00081
00082 debug_log("leaving dispatcher %p", this);
00083 }
00084
00085 void BusDispatcher::leave()
00086 {
00087 _running = false;
00088 }
00089
00090 void BusDispatcher::run()
00091 {
00092 _running = true;
00093 }
00094
00095 bool BusDispatcher::is_running()
00096 {
00097 return _running;
00098 }
00099
00100 void BusDispatcher::do_iteration()
00101 {
00102 dispatch_pending();
00103 dispatch();
00104 }
00105
00106 Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
00107 {
00108 BusTimeout *bt = new BusTimeout(ti, this);
00109
00110 bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
00111 bt->data(bt);
00112
00113 debug_log("added timeout %p (%s) interval=%d",
00114 bt, ((Timeout *)bt)->enabled() ? "on":"off", ((Timeout *)bt)->interval());
00115
00116 return bt;
00117 }
00118
00119 void BusDispatcher::rem_timeout(Timeout *t)
00120 {
00121 debug_log("removed timeout %p", t);
00122
00123 delete t;
00124 }
00125
00126 Watch *BusDispatcher::add_watch(Watch::Internal *wi)
00127 {
00128 BusWatch *bw = new BusWatch(wi, this);
00129
00130 bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
00131 bw->data(bw);
00132
00133 debug_log("added watch %p (%s) fd=%d flags=%d",
00134 bw, ((Watch *)bw)->enabled() ? "on":"off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
00135
00136 return bw;
00137 }
00138
00139 void BusDispatcher::rem_watch(Watch *w)
00140 {
00141 debug_log("removed watch %p", w);
00142
00143 delete w;
00144 }
00145
00146 void BusDispatcher::timeout_expired(DefaultTimeout &et)
00147 {
00148 debug_log("timeout %p expired", &et);
00149
00150 BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
00151
00152 timeout->handle();
00153 }
00154
00155 void BusDispatcher::watch_ready(DefaultWatch &ew)
00156 {
00157 BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
00158
00159 debug_log("watch %p ready, flags=%d state=%d",
00160 watch, ((Watch *)watch)->flags(), watch->state()
00161 );
00162
00163 int flags = 0;
00164
00165 if (watch->state() & POLLIN)
00166 flags |= DBUS_WATCH_READABLE;
00167 if (watch->state() & POLLOUT)
00168 flags |= DBUS_WATCH_WRITABLE;
00169 if (watch->state() & POLLHUP)
00170 flags |= DBUS_WATCH_HANGUP;
00171 if (watch->state() & POLLERR)
00172 flags |= DBUS_WATCH_ERROR;
00173
00174 watch->handle(flags);
00175 }
00176