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