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