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