25 #include "dbus-mainloop.h"
27 #ifndef DOXYGEN_SHOULD_SKIP_THIS
29 #include <dbus/dbus-list.h>
30 #include <dbus/dbus-sysdeps.h>
31 #include <dbus/dbus-watch.h>
33 #define MAINLOOP_SPEW 0
36 #ifdef DBUS_ENABLE_VERBOSE_MODE
38 watch_flags_to_string (
int flags)
40 const char *watch_type;
44 watch_type =
"readwrite";
45 else if (flags & DBUS_WATCH_READABLE)
47 else if (flags & DBUS_WATCH_WRITABLE)
50 watch_type =
"not read or write";
60 int callback_list_serial;
84 DBusWatchFunction
function;
87 unsigned int last_iteration_oom : 1;
94 DBusTimeoutFunction
function;
95 unsigned long last_tv_sec;
96 unsigned long last_tv_usec;
99 #define WATCH_CALLBACK(callback) ((WatchCallback*)callback)
100 #define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback)
102 static WatchCallback*
104 DBusWatchFunction
function,
115 cb->function =
function;
116 cb->last_iteration_oom =
FALSE;
117 cb->callback.refcount = 1;
118 cb->callback.type = CALLBACK_WATCH;
119 cb->callback.data = data;
120 cb->callback.free_data_func = free_data_func;
125 static TimeoutCallback*
127 DBusTimeoutFunction
function,
137 cb->timeout = timeout;
138 cb->function =
function;
141 cb->callback.refcount = 1;
142 cb->callback.type = CALLBACK_TIMEOUT;
143 cb->callback.data = data;
144 cb->callback.free_data_func = free_data_func;
150 callback_ref (Callback *cb)
160 callback_unref (Callback *cb)
166 if (cb->refcount == 0)
168 if (cb->free_data_func)
169 (* cb->free_data_func) (cb->data);
176 add_callback (DBusLoop *loop,
182 loop->callback_list_serial += 1;
187 loop->watch_count += 1;
189 case CALLBACK_TIMEOUT:
190 loop->timeout_count += 1;
198 remove_callback (DBusLoop *loop,
201 Callback *cb = link->
data;
206 loop->watch_count -= 1;
208 case CALLBACK_TIMEOUT:
209 loop->timeout_count -= 1;
215 loop->callback_list_serial += 1;
219 _dbus_loop_new (
void)
233 _dbus_loop_ref (DBusLoop *loop)
244 _dbus_loop_unref (DBusLoop *loop)
250 if (loop->refcount == 0)
252 while (loop->need_dispatch)
264 _dbus_loop_add_watch (DBusLoop *loop,
266 DBusWatchFunction
function,
272 wcb = watch_callback_new (watch,
function, data, free_data_func);
276 if (!add_callback (loop, (Callback*) wcb))
278 wcb->callback.free_data_func =
NULL;
279 callback_unref ((Callback*) wcb);
287 _dbus_loop_remove_watch (DBusLoop *loop,
289 DBusWatchFunction
function,
298 Callback *
this = link->
data;
300 if (this->type == CALLBACK_WATCH &&
301 WATCH_CALLBACK (
this)->watch == watch &&
302 this->data == data &&
303 WATCH_CALLBACK (
this)->
function ==
function)
305 remove_callback (loop, link);
313 _dbus_warn (
"could not find watch %p function %p data %p to remove\n",
314 watch, (
void *)
function, data);
318 _dbus_loop_add_timeout (DBusLoop *loop,
320 DBusTimeoutFunction
function,
324 TimeoutCallback *tcb;
326 tcb = timeout_callback_new (timeout,
function, data, free_data_func);
330 if (!add_callback (loop, (Callback*) tcb))
332 tcb->callback.free_data_func =
NULL;
333 callback_unref ((Callback*) tcb);
341 _dbus_loop_remove_timeout (DBusLoop *loop,
343 DBusTimeoutFunction
function,
352 Callback *
this = link->
data;
354 if (this->type == CALLBACK_TIMEOUT &&
355 TIMEOUT_CALLBACK (
this)->timeout == timeout &&
356 this->data == data &&
357 TIMEOUT_CALLBACK (
this)->
function ==
function)
359 remove_callback (loop, link);
367 _dbus_warn (
"could not find timeout %p function %p data %p to remove\n",
368 timeout, (
void *)
function, data);
375 check_timeout (
unsigned long tv_sec,
376 unsigned long tv_usec,
377 TimeoutCallback *tcb,
382 unsigned long expiration_tv_sec;
383 unsigned long expiration_tv_usec;
384 long interval_seconds;
385 long interval_milliseconds;
392 interval_seconds = interval / 1000L;
393 interval_milliseconds = interval % 1000L;
395 expiration_tv_sec = tcb->last_tv_sec + interval_seconds;
396 expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000;
397 if (expiration_tv_usec >= 1000000)
399 expiration_tv_usec -= 1000000;
400 expiration_tv_sec += 1;
403 sec_remaining = expiration_tv_sec - tv_sec;
407 msec_remaining = ((long) expiration_tv_usec - (
long) tv_usec) / 1000L;
410 _dbus_verbose (
"Interval is %ld seconds %ld msecs\n",
412 interval_milliseconds);
413 _dbus_verbose (
"Now is %lu seconds %lu usecs\n",
415 _dbus_verbose (
"Last is %lu seconds %lu usecs\n",
416 tcb->last_tv_sec, tcb->last_tv_usec);
417 _dbus_verbose (
"Exp is %lu seconds %lu usecs\n",
418 expiration_tv_sec, expiration_tv_usec);
419 _dbus_verbose (
"Pre-correction, sec_remaining %ld msec_remaining %ld\n",
420 sec_remaining, msec_remaining);
427 if (sec_remaining < 0 || (sec_remaining == 0 && msec_remaining < 0))
433 if (msec_remaining < 0)
435 msec_remaining += 1000;
443 *timeout = sec_remaining * 1000 + msec_remaining;
446 if (*timeout > interval)
449 _dbus_verbose (
"System clock set backward! Resetting timeout.\n");
451 tcb->last_tv_sec = tv_sec;
452 tcb->last_tv_usec = tv_usec;
458 _dbus_verbose (
" timeout expires in %d milliseconds\n", *timeout);
461 return *timeout == 0;
465 _dbus_loop_dispatch (DBusLoop *loop)
472 if (loop->need_dispatch ==
NULL)
476 while (loop->need_dispatch !=
NULL)
494 _dbus_wait_for_memory ();
503 _dbus_loop_queue_dispatch (DBusLoop *loop,
520 _dbus_loop_iterate (DBusLoop *loop,
523 #define N_STACK_DESCRIPTORS 64
528 WatchCallback **watches_for_fds;
529 WatchCallback *stack_watches_for_fds[N_STACK_DESCRIPTORS];
541 watches_for_fds =
NULL;
543 oom_watch_pending =
FALSE;
544 orig_depth = loop->depth;
547 _dbus_verbose (
"Iteration block=%d depth=%d timeout_count=%d watch_count=%d\n",
548 block, loop->depth, loop->timeout_count, loop->watch_count);
551 if (loop->callbacks ==
NULL)
554 if (loop->watch_count > N_STACK_DESCRIPTORS)
560 _dbus_wait_for_memory ();
564 watches_for_fds =
dbus_new (WatchCallback*, loop->watch_count);
565 while (watches_for_fds ==
NULL)
567 _dbus_wait_for_memory ();
568 watches_for_fds =
dbus_new (WatchCallback*, loop->watch_count);
574 watches_for_fds = stack_watches_for_fds;
583 Callback *cb = link->
data;
584 if (cb->type == CALLBACK_WATCH)
587 WatchCallback *wcb = WATCH_CALLBACK (cb);
590 if (wcb->last_iteration_oom)
595 wcb->last_iteration_oom =
FALSE;
596 oom_watch_pending =
TRUE;
603 _dbus_verbose (
" skipping watch on fd %d as it was out of memory last time\n",
607 else if (_DBUS_UNLIKELY (fd == -1))
609 _dbus_warn (
"watch %p was invalidated but not removed; "
610 "removing it now\n", wcb->watch);
611 _dbus_loop_remove_watch (loop, wcb->watch, wcb->function,
612 ((Callback *)wcb)->data);
616 watches_for_fds[n_fds] = wcb;
625 if (flags & DBUS_WATCH_READABLE)
627 if (flags & DBUS_WATCH_WRITABLE)
631 _dbus_verbose (
" polling watch on fd %d %s\n",
632 fd, watch_flags_to_string (flags));
640 _dbus_verbose (
" skipping disabled watch on fd %d %s\n",
651 if (loop->timeout_count > 0)
653 unsigned long tv_sec;
654 unsigned long tv_usec;
662 Callback *cb = link->
data;
664 if (cb->type == CALLBACK_TIMEOUT &&
667 TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb);
670 check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining);
673 timeout = msecs_remaining;
675 timeout = MIN (msecs_remaining, timeout);
678 _dbus_verbose (
" timeout added, %d remaining, aggregate timeout %ld\n",
679 msecs_remaining, timeout);
688 else if (cb->type == CALLBACK_TIMEOUT)
690 _dbus_verbose (
" skipping disabled timeout\n");
699 if (!block || loop->need_dispatch !=
NULL)
703 _dbus_verbose (
" timeout is 0 as we aren't blocking\n");
710 if (oom_watch_pending)
711 timeout = MIN (timeout, _dbus_get_oom_wait ());
714 _dbus_verbose (
" polling on %d descriptors timeout %ld\n", n_fds, timeout);
719 initial_serial = loop->callback_list_serial;
721 if (loop->timeout_count > 0)
723 unsigned long tv_sec;
724 unsigned long tv_usec;
733 Callback *cb = link->
data;
735 if (initial_serial != loop->callback_list_serial)
738 if (loop->depth != orig_depth)
741 if (cb->type == CALLBACK_TIMEOUT &&
744 TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb);
747 if (check_timeout (tv_sec, tv_usec,
748 tcb, &msecs_remaining))
751 tcb->last_tv_sec = tv_sec;
752 tcb->last_tv_usec = tv_usec;
755 _dbus_verbose (
" invoking timeout\n");
758 (* tcb->function) (tcb->timeout,
766 _dbus_verbose (
" timeout has not expired\n");
771 else if (cb->type == CALLBACK_TIMEOUT)
773 _dbus_verbose (
" skipping invocation of disabled timeout\n");
790 if (initial_serial != loop->callback_list_serial)
793 if (loop->depth != orig_depth)
796 if (fds[i].revents != 0)
799 unsigned int condition;
801 wcb = watches_for_fds[i];
817 if (condition != 0 &&
820 if (!(* wcb->function) (wcb->watch,
822 ((Callback*)wcb)->data))
823 wcb->last_iteration_oom =
TRUE;
826 _dbus_verbose (
" Invoked watch, oom = %d\n",
827 wcb->last_iteration_oom);
835 _dbus_warn (
"invalid request, socket fd %d not open\n",
838 _dbus_loop_remove_watch (loop, wcb->watch, wcb->function,
839 ((Callback *)wcb)->data);
849 _dbus_verbose (
" moving to next iteration\n");
852 if (fds && fds != stack_fds)
859 callback_unref (&watches_for_fds[i]->callback);
863 if (watches_for_fds != stack_watches_for_fds)
867 if (_dbus_loop_dispatch (loop))
871 _dbus_verbose (
"Returning %d\n", retval);
878 _dbus_loop_run (DBusLoop *loop)
884 _dbus_loop_ref (loop);
886 our_exit_depth = loop->depth;
889 _dbus_verbose (
"Running main loop, depth %d -> %d\n",
890 loop->depth - 1, loop->depth);
892 while (loop->depth != our_exit_depth)
893 _dbus_loop_iterate (loop,
TRUE);
895 _dbus_loop_unref (loop);
899 _dbus_loop_quit (DBusLoop *loop)
905 _dbus_verbose (
"Quit main loop, depth %d -> %d\n",
906 loop->depth + 1, loop->depth);
910 _dbus_get_oom_wait (
void)
912 #ifdef DBUS_BUILD_TESTS
921 _dbus_wait_for_memory (
void)
923 _dbus_verbose (
"Waiting for more memory\n");