26 #include "dbus-mainloop.h" 
   28 #ifndef DOXYGEN_SHOULD_SKIP_THIS 
   30 #include <dbus/dbus-hash.h> 
   31 #include <dbus/dbus-list.h> 
   32 #include <dbus/dbus-socket-set.h> 
   33 #include <dbus/dbus-timeout.h> 
   34 #include <dbus/dbus-watch.h> 
   36 #define MAINLOOP_SPEW 0 
   43   DBusSocketSet *socket_set;
 
   45   int callback_list_serial;
 
   52   unsigned oom_watch_pending : 1;
 
   62 #define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback) 
   64 static TimeoutCallback*
 
   73   cb->timeout = timeout;
 
   80 timeout_callback_free (TimeoutCallback *cb)
 
   86 free_watch_table_entry (
void *data)
 
  108 _dbus_loop_new (
void)
 
  117                                         free_watch_table_entry);
 
  119   loop->socket_set = _dbus_socket_set_new (0);
 
  121   if (loop->watches == 
NULL || loop->socket_set == 
NULL)
 
  123       if (loop->watches != 
NULL)
 
  126       if (loop->socket_set != 
NULL)
 
  127         _dbus_socket_set_free (loop->socket_set);
 
  139 _dbus_loop_ref (DBusLoop *loop)
 
  150 _dbus_loop_unref (DBusLoop *loop)
 
  156   if (loop->refcount == 0)
 
  158       while (loop->need_dispatch)
 
  166       _dbus_socket_set_free (loop->socket_set);
 
  172 ensure_watch_table_entry (DBusLoop    *loop,
 
  177   watches = _dbus_hash_table_lookup_pollable (loop->watches, fd);
 
  186       if (!_dbus_hash_table_insert_pollable (loop->watches, fd, watches))
 
  197 cull_watches_for_invalid_fd (DBusLoop     *loop,
 
  203   _dbus_warn (
"invalid request, socket fd %" DBUS_POLLABLE_FORMAT 
" not open",
 
  204               _dbus_pollable_printable (fd));
 
  205   watches = _dbus_hash_table_lookup_pollable (loop->watches, fd);
 
  215   _dbus_hash_table_remove_pollable (loop->watches, fd);
 
  219 gc_watch_table_entry (DBusLoop      *loop,
 
  228   if (*watches != 
NULL)
 
  231   _dbus_hash_table_remove_pollable (loop->watches, fd);
 
  236 refresh_watches_for_fd (DBusLoop      *loop,
 
  241   unsigned int flags = 0;
 
  247     watches = _dbus_hash_table_lookup_pollable (loop->watches, fd);
 
  258           !_dbus_watch_get_oom_last_time (link->
data))
 
  266     _dbus_socket_set_enable (loop->socket_set, fd, flags);
 
  268     _dbus_socket_set_disable (loop->socket_set, fd);
 
  272 _dbus_loop_add_watch (DBusLoop  *loop,
 
  278   fd = _dbus_watch_get_pollable (watch);
 
  281   watches = ensure_watch_table_entry (loop, fd);
 
  289       gc_watch_table_entry (loop, watches, fd);
 
  296       if (!_dbus_socket_set_add (loop->socket_set, fd,
 
  300           _dbus_hash_table_remove_pollable (loop->watches, fd);
 
  307       refresh_watches_for_fd (loop, watches, fd);
 
  310   loop->callback_list_serial += 1;
 
  311   loop->watch_count += 1;
 
  316 _dbus_loop_toggle_watch (DBusLoop          *loop,
 
  319   refresh_watches_for_fd (loop, 
NULL, _dbus_watch_get_pollable (watch));
 
  323 _dbus_loop_remove_watch (DBusLoop         *loop,
 
  333   fd = _dbus_watch_get_pollable (watch);
 
  336   watches = _dbus_hash_table_lookup_pollable (loop->watches, fd);
 
  349               loop->callback_list_serial += 1;
 
  350               loop->watch_count -= 1;
 
  355               if (gc_watch_table_entry (loop, watches, fd))
 
  357                   _dbus_socket_set_remove (loop->socket_set, fd);
 
  367   _dbus_warn (
"could not find watch %p to remove", watch);
 
  371 _dbus_loop_add_timeout (DBusLoop           *loop,
 
  374   TimeoutCallback *tcb;
 
  376   tcb = timeout_callback_new (timeout);
 
  382       loop->callback_list_serial += 1;
 
  383       loop->timeout_count += 1;
 
  387       timeout_callback_free (tcb);
 
  395 _dbus_loop_remove_timeout (DBusLoop           *loop,
 
  404       TimeoutCallback *
this = link->
data;
 
  406       if (this->timeout == timeout)
 
  409           loop->callback_list_serial += 1;
 
  410           loop->timeout_count -= 1;
 
  411           timeout_callback_free (
this);
 
  419   _dbus_warn (
"could not find timeout %p to remove", timeout);
 
  426 check_timeout (
long            tv_sec,
 
  428                TimeoutCallback *tcb,
 
  433   long expiration_tv_sec;
 
  434   long expiration_tv_usec;
 
  435   long interval_seconds;
 
  436   long interval_milliseconds;
 
  443   interval_seconds = interval / 1000L;
 
  444   interval_milliseconds = interval % 1000L;
 
  446   expiration_tv_sec = tcb->last_tv_sec + interval_seconds;
 
  447   expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000;
 
  448   if (expiration_tv_usec >= 1000000)
 
  450       expiration_tv_usec -= 1000000;
 
  451       expiration_tv_sec += 1;
 
  454   sec_remaining = expiration_tv_sec - tv_sec;
 
  455   msec_remaining = (expiration_tv_usec - tv_usec) / 1000L;
 
  458   _dbus_verbose (
"Interval is %ld seconds %ld msecs\n",
 
  460                  interval_milliseconds);
 
  461   _dbus_verbose (
"Now is  %lu seconds %lu usecs\n",
 
  463   _dbus_verbose (
"Last is %lu seconds %lu usecs\n",
 
  464                  tcb->last_tv_sec, tcb->last_tv_usec);
 
  465   _dbus_verbose (
"Exp is  %lu seconds %lu usecs\n",
 
  466                  expiration_tv_sec, expiration_tv_usec);
 
  467   _dbus_verbose (
"Pre-correction, sec_remaining %ld msec_remaining %ld\n",
 
  468                  sec_remaining, msec_remaining);
 
  475   if (sec_remaining < 0 || (sec_remaining == 0 && msec_remaining < 0))
 
  481       if (msec_remaining < 0)
 
  483           msec_remaining += 1000;
 
  491         *timeout = sec_remaining * 1000 + msec_remaining;        
 
  494   if (*timeout > interval)
 
  497       _dbus_verbose (
"System clock set backward! Resetting timeout.\n");
 
  499       tcb->last_tv_sec = tv_sec;
 
  500       tcb->last_tv_usec = tv_usec;
 
  506   _dbus_verbose (
"  timeout expires in %d milliseconds\n", *timeout);
 
  509   return *timeout == 0;
 
  513 _dbus_loop_dispatch (DBusLoop *loop)
 
  520   if (loop->need_dispatch == 
NULL)
 
  524   while (loop->need_dispatch != 
NULL)
 
  542                 _dbus_wait_for_memory ();
 
  551 _dbus_loop_queue_dispatch (DBusLoop       *loop,
 
  568 _dbus_loop_iterate (DBusLoop     *loop,
 
  571 #define N_STACK_DESCRIPTORS 64 
  573   DBusSocketEvent ready_fds[N_STACK_DESCRIPTORS];
 
  583   orig_depth = loop->depth;
 
  586   _dbus_verbose (
"Iteration block=%d depth=%d timeout_count=%d watch_count=%d\n",
 
  587                  block, loop->depth, loop->timeout_count, loop->watch_count);
 
  591       loop->timeouts == 
NULL)
 
  595   if (loop->timeout_count > 0)
 
  606           TimeoutCallback *tcb = link->
data;
 
  614                   tcb->last_tv_sec = tv_sec;
 
  615                   tcb->last_tv_usec = tv_usec;
 
  619               check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining);
 
  622                 timeout = msecs_remaining;
 
  624                 timeout = MIN (msecs_remaining, timeout);
 
  627               _dbus_verbose (
"  timeout added, %d remaining, aggregate timeout %ld\n",
 
  628                              msecs_remaining, timeout);
 
  636               _dbus_verbose (
"  skipping disabled timeout\n");
 
  645   if (!block || loop->need_dispatch != 
NULL)
 
  649       _dbus_verbose (
"  timeout is 0 as we aren't blocking\n");
 
  656   if (loop->oom_watch_pending)
 
  657     timeout = MIN (timeout, _dbus_get_oom_wait ());
 
  660   _dbus_verbose (
"  polling on %d descriptors timeout %ld\n", 
_DBUS_N_ELEMENTS (ready_fds), timeout);
 
  663   n_ready = _dbus_socket_set_poll (loop->socket_set, ready_fds,
 
  667   if (loop->oom_watch_pending)
 
  671       loop->oom_watch_pending = 
FALSE;
 
  682           fd = _dbus_hash_iter_get_pollable_key (&hash_iter);
 
  691               if (_dbus_watch_get_oom_last_time (watch))
 
  693                   _dbus_watch_set_oom_last_time (watch, 
FALSE);
 
  699             refresh_watches_for_fd (loop, watches, fd);
 
  706   initial_serial = loop->callback_list_serial;
 
  708   if (loop->timeout_count > 0)
 
  720           TimeoutCallback *tcb = link->
data;
 
  722           if (initial_serial != loop->callback_list_serial)
 
  725           if (loop->depth != orig_depth)
 
  732               if (check_timeout (tv_sec, tv_usec,
 
  733                                  tcb, &msecs_remaining))
 
  736                   tcb->last_tv_sec = tv_sec;
 
  737                   tcb->last_tv_usec = tv_usec;
 
  740                   _dbus_verbose (
"  invoking timeout\n");
 
  753                   _dbus_verbose (
"  timeout has not expired\n");
 
  760               _dbus_verbose (
"  skipping invocation of disabled timeout\n");
 
  770       for (i = 0; i < n_ready; i++)
 
  774           unsigned int condition;
 
  781           if (initial_serial != loop->callback_list_serial)
 
  784           if (loop->depth != orig_depth)
 
  789           if (_DBUS_UNLIKELY (ready_fds[i].flags & _DBUS_WATCH_NVAL))
 
  791               cull_watches_for_invalid_fd (loop, ready_fds[i].fd);
 
  795           condition = ready_fds[i].flags;
 
  804           watches = _dbus_hash_table_lookup_pollable (loop->watches,
 
  828                       _dbus_watch_set_oom_last_time (watch, 
TRUE);
 
  829                       loop->oom_watch_pending = 
TRUE;
 
  834                   _dbus_verbose (
"  Invoked watch, oom = %d\n", oom);
 
  841                   if (initial_serial != loop->callback_list_serial ||
 
  842                       loop->depth != orig_depth)
 
  845                         refresh_watches_for_fd (loop, 
NULL, ready_fds[i].fd);
 
  853             refresh_watches_for_fd (loop, watches, ready_fds[i].fd);
 
  859   _dbus_verbose (
"  moving to next iteration\n");
 
  862   if (_dbus_loop_dispatch (loop))
 
  866   _dbus_verbose (
"Returning %d\n", retval);
 
  873 _dbus_loop_run (DBusLoop *loop)
 
  879   _dbus_loop_ref (loop);
 
  881   our_exit_depth = loop->depth;
 
  884   _dbus_verbose (
"Running main loop, depth %d -> %d\n",
 
  885                  loop->depth - 1, loop->depth);
 
  887   while (loop->depth != our_exit_depth)
 
  888     _dbus_loop_iterate (loop, 
TRUE);
 
  890   _dbus_loop_unref (loop);
 
  894 _dbus_loop_quit (DBusLoop *loop)
 
  900   _dbus_verbose (
"Quit main loop, depth %d -> %d\n",
 
  901                  loop->depth + 1, loop->depth);
 
  905 _dbus_get_oom_wait (
void)
 
  907 #ifdef DBUS_ENABLE_EMBEDDED_TESTS 
  916 _dbus_wait_for_memory (
void)
 
  918   _dbus_verbose (
"Waiting for more memory\n");