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 #include <config.h>
00026 #include "dbus-mainloop.h"
00027
00028 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00029
00030 #include <dbus/dbus-hash.h>
00031 #include <dbus/dbus-list.h>
00032 #include <dbus/dbus-socket-set.h>
00033 #include <dbus/dbus-watch.h>
00034
00035 #define MAINLOOP_SPEW 0
00036
00037 #if MAINLOOP_SPEW
00038 #ifdef DBUS_ENABLE_VERBOSE_MODE
00039 static const char*
00040 watch_flags_to_string (int flags)
00041 {
00042 const char *watch_type;
00043
00044 if ((flags & DBUS_WATCH_READABLE) &&
00045 (flags & DBUS_WATCH_WRITABLE))
00046 watch_type = "readwrite";
00047 else if (flags & DBUS_WATCH_READABLE)
00048 watch_type = "read";
00049 else if (flags & DBUS_WATCH_WRITABLE)
00050 watch_type = "write";
00051 else
00052 watch_type = "not read or write";
00053 return watch_type;
00054 }
00055 #endif
00056 #endif
00057
00058 struct DBusLoop
00059 {
00060 int refcount;
00062 DBusHashTable *watches;
00063 DBusSocketSet *socket_set;
00064 DBusList *timeouts;
00065 int callback_list_serial;
00066 int watch_count;
00067 int timeout_count;
00068 int depth;
00069 DBusList *need_dispatch;
00072 unsigned oom_watch_pending : 1;
00073 };
00074
00075 typedef struct
00076 {
00077 DBusTimeout *timeout;
00078 unsigned long last_tv_sec;
00079 unsigned long last_tv_usec;
00080 } TimeoutCallback;
00081
00082 #define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback)
00083
00084 static TimeoutCallback*
00085 timeout_callback_new (DBusTimeout *timeout)
00086 {
00087 TimeoutCallback *cb;
00088
00089 cb = dbus_new (TimeoutCallback, 1);
00090 if (cb == NULL)
00091 return NULL;
00092
00093 cb->timeout = timeout;
00094 _dbus_get_monotonic_time (&cb->last_tv_sec,
00095 &cb->last_tv_usec);
00096 return cb;
00097 }
00098
00099 static void
00100 timeout_callback_free (TimeoutCallback *cb)
00101 {
00102 dbus_free (cb);
00103 }
00104
00105 static void
00106 free_watch_table_entry (void *data)
00107 {
00108 DBusList **watches = data;
00109 DBusWatch *watch;
00110
00111
00112
00113 if (watches == NULL)
00114 return;
00115
00116 for (watch = _dbus_list_pop_first (watches);
00117 watch != NULL;
00118 watch = _dbus_list_pop_first (watches))
00119 {
00120 _dbus_watch_unref (watch);
00121 }
00122
00123 _dbus_assert (*watches == NULL);
00124 dbus_free (watches);
00125 }
00126
00127 DBusLoop*
00128 _dbus_loop_new (void)
00129 {
00130 DBusLoop *loop;
00131
00132 loop = dbus_new0 (DBusLoop, 1);
00133 if (loop == NULL)
00134 return NULL;
00135
00136 loop->watches = _dbus_hash_table_new (DBUS_HASH_INT, NULL,
00137 free_watch_table_entry);
00138
00139 loop->socket_set = _dbus_socket_set_new (0);
00140
00141 if (loop->watches == NULL || loop->socket_set == NULL)
00142 {
00143 if (loop->watches != NULL)
00144 _dbus_hash_table_unref (loop->watches);
00145
00146 if (loop->socket_set != NULL)
00147 _dbus_socket_set_free (loop->socket_set);
00148
00149 dbus_free (loop);
00150 return NULL;
00151 }
00152
00153 loop->refcount = 1;
00154
00155 return loop;
00156 }
00157
00158 DBusLoop *
00159 _dbus_loop_ref (DBusLoop *loop)
00160 {
00161 _dbus_assert (loop != NULL);
00162 _dbus_assert (loop->refcount > 0);
00163
00164 loop->refcount += 1;
00165
00166 return loop;
00167 }
00168
00169 void
00170 _dbus_loop_unref (DBusLoop *loop)
00171 {
00172 _dbus_assert (loop != NULL);
00173 _dbus_assert (loop->refcount > 0);
00174
00175 loop->refcount -= 1;
00176 if (loop->refcount == 0)
00177 {
00178 while (loop->need_dispatch)
00179 {
00180 DBusConnection *connection = _dbus_list_pop_first (&loop->need_dispatch);
00181
00182 dbus_connection_unref (connection);
00183 }
00184
00185 _dbus_hash_table_unref (loop->watches);
00186 _dbus_socket_set_free (loop->socket_set);
00187 dbus_free (loop);
00188 }
00189 }
00190
00191 static DBusList **
00192 ensure_watch_table_entry (DBusLoop *loop,
00193 int fd)
00194 {
00195 DBusList **watches;
00196
00197 watches = _dbus_hash_table_lookup_int (loop->watches, fd);
00198
00199 if (watches == NULL)
00200 {
00201 watches = dbus_new0 (DBusList *, 1);
00202
00203 if (watches == NULL)
00204 return watches;
00205
00206 if (!_dbus_hash_table_insert_int (loop->watches, fd, watches))
00207 {
00208 dbus_free (watches);
00209 watches = NULL;
00210 }
00211 }
00212
00213 return watches;
00214 }
00215
00216 static void
00217 cull_watches_for_invalid_fd (DBusLoop *loop,
00218 int fd)
00219 {
00220 DBusList *link;
00221 DBusList **watches;
00222
00223 _dbus_warn ("invalid request, socket fd %d not open\n", fd);
00224 watches = _dbus_hash_table_lookup_int (loop->watches, fd);
00225
00226 if (watches != NULL)
00227 {
00228 for (link = _dbus_list_get_first_link (watches);
00229 link != NULL;
00230 link = _dbus_list_get_next_link (watches, link))
00231 _dbus_watch_invalidate (link->data);
00232 }
00233
00234 _dbus_hash_table_remove_int (loop->watches, fd);
00235 }
00236
00237 static dbus_bool_t
00238 gc_watch_table_entry (DBusLoop *loop,
00239 DBusList **watches,
00240 int fd)
00241 {
00242
00243 if (watches == NULL)
00244 return FALSE;
00245
00246
00247 if (*watches != NULL)
00248 return FALSE;
00249
00250 _dbus_hash_table_remove_int (loop->watches, fd);
00251 return TRUE;
00252 }
00253
00254 static void
00255 refresh_watches_for_fd (DBusLoop *loop,
00256 DBusList **watches,
00257 int fd)
00258 {
00259 DBusList *link;
00260 unsigned int flags = 0;
00261 dbus_bool_t interested = FALSE;
00262
00263 _dbus_assert (fd != -1);
00264
00265 if (watches == NULL)
00266 watches = _dbus_hash_table_lookup_int (loop->watches, fd);
00267
00268
00269
00270 _dbus_assert (watches != NULL);
00271
00272 for (link = _dbus_list_get_first_link (watches);
00273 link != NULL;
00274 link = _dbus_list_get_next_link (watches, link))
00275 {
00276 if (dbus_watch_get_enabled (link->data) &&
00277 !_dbus_watch_get_oom_last_time (link->data))
00278 {
00279 flags |= dbus_watch_get_flags (link->data);
00280 interested = TRUE;
00281 }
00282 }
00283
00284 if (interested)
00285 _dbus_socket_set_enable (loop->socket_set, fd, flags);
00286 else
00287 _dbus_socket_set_disable (loop->socket_set, fd);
00288 }
00289
00290 dbus_bool_t
00291 _dbus_loop_add_watch (DBusLoop *loop,
00292 DBusWatch *watch)
00293 {
00294 int fd;
00295 DBusList **watches;
00296
00297 fd = dbus_watch_get_socket (watch);
00298 _dbus_assert (fd != -1);
00299
00300 watches = ensure_watch_table_entry (loop, fd);
00301
00302 if (watches == NULL)
00303 return FALSE;
00304
00305 if (!_dbus_list_append (watches, _dbus_watch_ref (watch)))
00306 {
00307 _dbus_watch_unref (watch);
00308 gc_watch_table_entry (loop, watches, fd);
00309
00310 return FALSE;
00311 }
00312
00313 if (_dbus_list_length_is_one (watches))
00314 {
00315 if (!_dbus_socket_set_add (loop->socket_set, fd,
00316 dbus_watch_get_flags (watch),
00317 dbus_watch_get_enabled (watch)))
00318 {
00319 _dbus_hash_table_remove_int (loop->watches, fd);
00320 return FALSE;
00321 }
00322 }
00323 else
00324 {
00325
00326 refresh_watches_for_fd (loop, watches, fd);
00327 }
00328
00329 loop->callback_list_serial += 1;
00330 loop->watch_count += 1;
00331 return TRUE;
00332 }
00333
00334 void
00335 _dbus_loop_toggle_watch (DBusLoop *loop,
00336 DBusWatch *watch)
00337 {
00338 refresh_watches_for_fd (loop, NULL, dbus_watch_get_socket (watch));
00339 }
00340
00341 void
00342 _dbus_loop_remove_watch (DBusLoop *loop,
00343 DBusWatch *watch)
00344 {
00345 DBusList **watches;
00346 DBusList *link;
00347 int fd;
00348
00349
00350
00351
00352 fd = dbus_watch_get_socket (watch);
00353 _dbus_assert (fd != -1);
00354
00355 watches = _dbus_hash_table_lookup_int (loop->watches, fd);
00356
00357 if (watches != NULL)
00358 {
00359 link = _dbus_list_get_first_link (watches);
00360 while (link != NULL)
00361 {
00362 DBusList *next = _dbus_list_get_next_link (watches, link);
00363 DBusWatch *this = link->data;
00364
00365 if (this == watch)
00366 {
00367 _dbus_list_remove_link (watches, link);
00368 loop->callback_list_serial += 1;
00369 loop->watch_count -= 1;
00370 _dbus_watch_unref (this);
00371
00372
00373
00374 if (gc_watch_table_entry (loop, watches, fd))
00375 {
00376 _dbus_socket_set_remove (loop->socket_set, fd);
00377 }
00378
00379 return;
00380 }
00381
00382 link = next;
00383 }
00384 }
00385
00386 _dbus_warn ("could not find watch %p to remove\n", watch);
00387 }
00388
00389 dbus_bool_t
00390 _dbus_loop_add_timeout (DBusLoop *loop,
00391 DBusTimeout *timeout)
00392 {
00393 TimeoutCallback *tcb;
00394
00395 tcb = timeout_callback_new (timeout);
00396 if (tcb == NULL)
00397 return FALSE;
00398
00399 if (_dbus_list_append (&loop->timeouts, tcb))
00400 {
00401 loop->callback_list_serial += 1;
00402 loop->timeout_count += 1;
00403 }
00404 else
00405 {
00406 timeout_callback_free (tcb);
00407 return FALSE;
00408 }
00409
00410 return TRUE;
00411 }
00412
00413 void
00414 _dbus_loop_remove_timeout (DBusLoop *loop,
00415 DBusTimeout *timeout)
00416 {
00417 DBusList *link;
00418
00419 link = _dbus_list_get_first_link (&loop->timeouts);
00420 while (link != NULL)
00421 {
00422 DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link);
00423 TimeoutCallback *this = link->data;
00424
00425 if (this->timeout == timeout)
00426 {
00427 _dbus_list_remove_link (&loop->timeouts, link);
00428 loop->callback_list_serial += 1;
00429 loop->timeout_count -= 1;
00430 timeout_callback_free (this);
00431
00432 return;
00433 }
00434
00435 link = next;
00436 }
00437
00438 _dbus_warn ("could not find timeout %p to remove\n", timeout);
00439 }
00440
00441
00442
00443
00444 static dbus_bool_t
00445 check_timeout (unsigned long tv_sec,
00446 unsigned long tv_usec,
00447 TimeoutCallback *tcb,
00448 int *timeout)
00449 {
00450 long sec_remaining;
00451 long msec_remaining;
00452 unsigned long expiration_tv_sec;
00453 unsigned long expiration_tv_usec;
00454 long interval_seconds;
00455 long interval_milliseconds;
00456 int interval;
00457
00458
00459
00460 interval = dbus_timeout_get_interval (tcb->timeout);
00461
00462 interval_seconds = interval / 1000L;
00463 interval_milliseconds = interval % 1000L;
00464
00465 expiration_tv_sec = tcb->last_tv_sec + interval_seconds;
00466 expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000;
00467 if (expiration_tv_usec >= 1000000)
00468 {
00469 expiration_tv_usec -= 1000000;
00470 expiration_tv_sec += 1;
00471 }
00472
00473 sec_remaining = expiration_tv_sec - tv_sec;
00474
00475
00476
00477 msec_remaining = ((long) expiration_tv_usec - (long) tv_usec) / 1000L;
00478
00479 #if MAINLOOP_SPEW
00480 _dbus_verbose ("Interval is %ld seconds %ld msecs\n",
00481 interval_seconds,
00482 interval_milliseconds);
00483 _dbus_verbose ("Now is %lu seconds %lu usecs\n",
00484 tv_sec, tv_usec);
00485 _dbus_verbose ("Last is %lu seconds %lu usecs\n",
00486 tcb->last_tv_sec, tcb->last_tv_usec);
00487 _dbus_verbose ("Exp is %lu seconds %lu usecs\n",
00488 expiration_tv_sec, expiration_tv_usec);
00489 _dbus_verbose ("Pre-correction, sec_remaining %ld msec_remaining %ld\n",
00490 sec_remaining, msec_remaining);
00491 #endif
00492
00493
00494
00495
00496
00497 if (sec_remaining < 0 || (sec_remaining == 0 && msec_remaining < 0))
00498 {
00499 *timeout = 0;
00500 }
00501 else
00502 {
00503 if (msec_remaining < 0)
00504 {
00505 msec_remaining += 1000;
00506 sec_remaining -= 1;
00507 }
00508
00509 if (sec_remaining > (_DBUS_INT_MAX / 1000) ||
00510 msec_remaining > _DBUS_INT_MAX)
00511 *timeout = _DBUS_INT_MAX;
00512 else
00513 *timeout = sec_remaining * 1000 + msec_remaining;
00514 }
00515
00516 if (*timeout > interval)
00517 {
00518
00519 _dbus_verbose ("System clock set backward! Resetting timeout.\n");
00520
00521 tcb->last_tv_sec = tv_sec;
00522 tcb->last_tv_usec = tv_usec;
00523
00524 *timeout = interval;
00525 }
00526
00527 #if MAINLOOP_SPEW
00528 _dbus_verbose (" timeout expires in %d milliseconds\n", *timeout);
00529 #endif
00530
00531 return *timeout == 0;
00532 }
00533
00534 dbus_bool_t
00535 _dbus_loop_dispatch (DBusLoop *loop)
00536 {
00537
00538 #if MAINLOOP_SPEW
00539 _dbus_verbose (" %d connections to dispatch\n", _dbus_list_get_length (&loop->need_dispatch));
00540 #endif
00541
00542 if (loop->need_dispatch == NULL)
00543 return FALSE;
00544
00545 next:
00546 while (loop->need_dispatch != NULL)
00547 {
00548 DBusConnection *connection = _dbus_list_pop_first (&loop->need_dispatch);
00549
00550 while (TRUE)
00551 {
00552 DBusDispatchStatus status;
00553
00554 status = dbus_connection_dispatch (connection);
00555
00556 if (status == DBUS_DISPATCH_COMPLETE)
00557 {
00558 dbus_connection_unref (connection);
00559 goto next;
00560 }
00561 else
00562 {
00563 if (status == DBUS_DISPATCH_NEED_MEMORY)
00564 _dbus_wait_for_memory ();
00565 }
00566 }
00567 }
00568
00569 return TRUE;
00570 }
00571
00572 dbus_bool_t
00573 _dbus_loop_queue_dispatch (DBusLoop *loop,
00574 DBusConnection *connection)
00575 {
00576 if (_dbus_list_append (&loop->need_dispatch, connection))
00577 {
00578 dbus_connection_ref (connection);
00579 return TRUE;
00580 }
00581 else
00582 return FALSE;
00583 }
00584
00585
00586
00587
00588
00589 dbus_bool_t
00590 _dbus_loop_iterate (DBusLoop *loop,
00591 dbus_bool_t block)
00592 {
00593 #define N_STACK_DESCRIPTORS 64
00594 dbus_bool_t retval;
00595 DBusSocketEvent ready_fds[N_STACK_DESCRIPTORS];
00596 int i;
00597 DBusList *link;
00598 int n_ready;
00599 int initial_serial;
00600 long timeout;
00601 int orig_depth;
00602
00603 retval = FALSE;
00604
00605 orig_depth = loop->depth;
00606
00607 #if MAINLOOP_SPEW
00608 _dbus_verbose ("Iteration block=%d depth=%d timeout_count=%d watch_count=%d\n",
00609 block, loop->depth, loop->timeout_count, loop->watch_count);
00610 #endif
00611
00612 if (_dbus_hash_table_get_n_entries (loop->watches) == 0 &&
00613 loop->timeouts == NULL)
00614 goto next_iteration;
00615
00616 timeout = -1;
00617 if (loop->timeout_count > 0)
00618 {
00619 unsigned long tv_sec;
00620 unsigned long tv_usec;
00621
00622 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
00623
00624 link = _dbus_list_get_first_link (&loop->timeouts);
00625 while (link != NULL)
00626 {
00627 DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link);
00628 TimeoutCallback *tcb = link->data;
00629
00630 if (dbus_timeout_get_enabled (tcb->timeout))
00631 {
00632 int msecs_remaining;
00633
00634 check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining);
00635
00636 if (timeout < 0)
00637 timeout = msecs_remaining;
00638 else
00639 timeout = MIN (msecs_remaining, timeout);
00640
00641 #if MAINLOOP_SPEW
00642 _dbus_verbose (" timeout added, %d remaining, aggregate timeout %ld\n",
00643 msecs_remaining, timeout);
00644 #endif
00645
00646 _dbus_assert (timeout >= 0);
00647
00648 if (timeout == 0)
00649 break;
00650 }
00651 #if MAINLOOP_SPEW
00652 else
00653 {
00654 _dbus_verbose (" skipping disabled timeout\n");
00655 }
00656 #endif
00657
00658 link = next;
00659 }
00660 }
00661
00662
00663 if (!block || loop->need_dispatch != NULL)
00664 {
00665 timeout = 0;
00666 #if MAINLOOP_SPEW
00667 _dbus_verbose (" timeout is 0 as we aren't blocking\n");
00668 #endif
00669 }
00670
00671
00672
00673
00674 if (loop->oom_watch_pending)
00675 timeout = MIN (timeout, _dbus_get_oom_wait ());
00676
00677 #if MAINLOOP_SPEW
00678 _dbus_verbose (" polling on %d descriptors timeout %ld\n", n_fds, timeout);
00679 #endif
00680
00681 n_ready = _dbus_socket_set_poll (loop->socket_set, ready_fds,
00682 _DBUS_N_ELEMENTS (ready_fds), timeout);
00683
00684
00685 if (loop->oom_watch_pending)
00686 {
00687 DBusHashIter hash_iter;
00688
00689 loop->oom_watch_pending = FALSE;
00690
00691 _dbus_hash_iter_init (loop->watches, &hash_iter);
00692
00693 while (_dbus_hash_iter_next (&hash_iter))
00694 {
00695 DBusList **watches;
00696 int fd;
00697 dbus_bool_t changed;
00698
00699 changed = FALSE;
00700 fd = _dbus_hash_iter_get_int_key (&hash_iter);
00701 watches = _dbus_hash_iter_get_value (&hash_iter);
00702
00703 for (link = _dbus_list_get_first_link (watches);
00704 link != NULL;
00705 link = _dbus_list_get_next_link (watches, link))
00706 {
00707 DBusWatch *watch = link->data;
00708
00709 if (_dbus_watch_get_oom_last_time (watch))
00710 {
00711 _dbus_watch_set_oom_last_time (watch, FALSE);
00712 changed = TRUE;
00713 }
00714 }
00715
00716 if (changed)
00717 refresh_watches_for_fd (loop, watches, fd);
00718 }
00719
00720 retval = TRUE;
00721
00722 }
00723
00724 initial_serial = loop->callback_list_serial;
00725
00726 if (loop->timeout_count > 0)
00727 {
00728 unsigned long tv_sec;
00729 unsigned long tv_usec;
00730
00731 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
00732
00733
00734 link = _dbus_list_get_first_link (&loop->timeouts);
00735 while (link != NULL)
00736 {
00737 DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link);
00738 TimeoutCallback *tcb = link->data;
00739
00740 if (initial_serial != loop->callback_list_serial)
00741 goto next_iteration;
00742
00743 if (loop->depth != orig_depth)
00744 goto next_iteration;
00745
00746 if (dbus_timeout_get_enabled (tcb->timeout))
00747 {
00748 int msecs_remaining;
00749
00750 if (check_timeout (tv_sec, tv_usec,
00751 tcb, &msecs_remaining))
00752 {
00753
00754 tcb->last_tv_sec = tv_sec;
00755 tcb->last_tv_usec = tv_usec;
00756
00757 #if MAINLOOP_SPEW
00758 _dbus_verbose (" invoking timeout\n");
00759 #endif
00760
00761
00762
00763
00764 dbus_timeout_handle (tcb->timeout);
00765
00766 retval = TRUE;
00767 }
00768 else
00769 {
00770 #if MAINLOOP_SPEW
00771 _dbus_verbose (" timeout has not expired\n");
00772 #endif
00773 }
00774 }
00775 #if MAINLOOP_SPEW
00776 else
00777 {
00778 _dbus_verbose (" skipping invocation of disabled timeout\n");
00779 }
00780 #endif
00781
00782 link = next;
00783 }
00784 }
00785
00786 if (n_ready > 0)
00787 {
00788 for (i = 0; i < n_ready; i++)
00789 {
00790 DBusList **watches;
00791 DBusList *next;
00792 unsigned int condition;
00793 dbus_bool_t any_oom;
00794
00795
00796
00797
00798
00799 if (initial_serial != loop->callback_list_serial)
00800 goto next_iteration;
00801
00802 if (loop->depth != orig_depth)
00803 goto next_iteration;
00804
00805 _dbus_assert (ready_fds[i].flags != 0);
00806
00807 if (_DBUS_UNLIKELY (ready_fds[i].flags & _DBUS_WATCH_NVAL))
00808 {
00809 cull_watches_for_invalid_fd (loop, ready_fds[i].fd);
00810 goto next_iteration;
00811 }
00812
00813 condition = ready_fds[i].flags;
00814 _dbus_assert ((condition & _DBUS_WATCH_NVAL) == 0);
00815
00816
00817
00818
00819 if (condition == 0)
00820 continue;
00821
00822 watches = _dbus_hash_table_lookup_int (loop->watches,
00823 ready_fds[i].fd);
00824
00825 if (watches == NULL)
00826 continue;
00827
00828 any_oom = FALSE;
00829
00830 for (link = _dbus_list_get_first_link (watches);
00831 link != NULL;
00832 link = next)
00833 {
00834 DBusWatch *watch = link->data;
00835
00836 next = _dbus_list_get_next_link (watches, link);
00837
00838 if (dbus_watch_get_enabled (watch))
00839 {
00840 dbus_bool_t oom;
00841
00842 oom = !dbus_watch_handle (watch, condition);
00843
00844 if (oom)
00845 {
00846 _dbus_watch_set_oom_last_time (watch, TRUE);
00847 loop->oom_watch_pending = TRUE;
00848 any_oom = TRUE;
00849 }
00850
00851 #if MAINLOOP_SPEW
00852 _dbus_verbose (" Invoked watch, oom = %d\n", oom);
00853 #endif
00854 retval = TRUE;
00855
00856
00857
00858
00859 if (initial_serial != loop->callback_list_serial ||
00860 loop->depth != orig_depth)
00861 {
00862 if (any_oom)
00863 refresh_watches_for_fd (loop, NULL, ready_fds[i].fd);
00864
00865 goto next_iteration;
00866 }
00867 }
00868 }
00869
00870 if (any_oom)
00871 refresh_watches_for_fd (loop, watches, ready_fds[i].fd);
00872 }
00873 }
00874
00875 next_iteration:
00876 #if MAINLOOP_SPEW
00877 _dbus_verbose (" moving to next iteration\n");
00878 #endif
00879
00880 if (_dbus_loop_dispatch (loop))
00881 retval = TRUE;
00882
00883 #if MAINLOOP_SPEW
00884 _dbus_verbose ("Returning %d\n", retval);
00885 #endif
00886
00887 return retval;
00888 }
00889
00890 void
00891 _dbus_loop_run (DBusLoop *loop)
00892 {
00893 int our_exit_depth;
00894
00895 _dbus_assert (loop->depth >= 0);
00896
00897 _dbus_loop_ref (loop);
00898
00899 our_exit_depth = loop->depth;
00900 loop->depth += 1;
00901
00902 _dbus_verbose ("Running main loop, depth %d -> %d\n",
00903 loop->depth - 1, loop->depth);
00904
00905 while (loop->depth != our_exit_depth)
00906 _dbus_loop_iterate (loop, TRUE);
00907
00908 _dbus_loop_unref (loop);
00909 }
00910
00911 void
00912 _dbus_loop_quit (DBusLoop *loop)
00913 {
00914 _dbus_assert (loop->depth > 0);
00915
00916 loop->depth -= 1;
00917
00918 _dbus_verbose ("Quit main loop, depth %d -> %d\n",
00919 loop->depth + 1, loop->depth);
00920 }
00921
00922 int
00923 _dbus_get_oom_wait (void)
00924 {
00925 #ifdef DBUS_BUILD_TESTS
00926
00927 return 0;
00928 #else
00929 return 500;
00930 #endif
00931 }
00932
00933 void
00934 _dbus_wait_for_memory (void)
00935 {
00936 _dbus_verbose ("Waiting for more memory\n");
00937 _dbus_sleep_milliseconds (_dbus_get_oom_wait ());
00938 }
00939
00940 #endif