diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-03-14 01:27:58 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-03-14 01:27:58 +0000 | 
| commit | 3bea935316ff048e68dea6a26c2e8e9fd314477f (patch) | |
| tree | 498e62121c89d78693070d04e6bc6a6462efe2a7 | |
| parent | 81c30364c291045d556c88f6818033104e627b6e (diff) | |
2003-03-13  Havoc Pennington  <hp@redhat.com>
	* dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle
	out of memory
	* dbus/dbus-watch.c (_dbus_watch_list_set_functions): handle out
	of memory
	* dbus/dbus-connection.h: Make AddWatchFunction and
	AddTimeoutFunction return a bool so they can fail on out-of-memory
	* bus/bus.c (bus_context_new): set up timeout handlers
	* bus/connection.c (bus_connections_setup_connection): set up
	timeout handlers
	* glib/dbus-gmain.c: adapt to the fact that set_functions stuff
	can fail
	* bus/bus.c (bus_context_new): adapt to changes
	* bus/connection.c: adapt to changes
	* test/watch.c: adapt to DBusWatch changes
	* bus/dispatch.c (bus_dispatch_test): started adding this but
	didn't finish
| -rw-r--r-- | ChangeLog | 28 | ||||
| -rw-r--r-- | bus/Makefile.am | 2 | ||||
| -rw-r--r-- | bus/bus.c | 68 | ||||
| -rw-r--r-- | bus/connection.c | 77 | ||||
| -rw-r--r-- | bus/dispatch.c | 85 | ||||
| -rw-r--r-- | bus/loop.c | 415 | ||||
| -rw-r--r-- | bus/loop.h | 34 | ||||
| -rw-r--r-- | bus/test-main.c | 25 | ||||
| -rw-r--r-- | bus/test.h | 2 | ||||
| -rw-r--r-- | dbus/dbus-connection.c | 36 | ||||
| -rw-r--r-- | dbus/dbus-connection.h | 54 | ||||
| -rw-r--r-- | dbus/dbus-server.c | 22 | ||||
| -rw-r--r-- | dbus/dbus-server.h | 45 | ||||
| -rw-r--r-- | dbus/dbus-timeout.c | 58 | ||||
| -rw-r--r-- | dbus/dbus-timeout.h | 2 | ||||
| -rw-r--r-- | dbus/dbus-watch.c | 58 | ||||
| -rw-r--r-- | dbus/dbus-watch.h | 2 | ||||
| -rw-r--r-- | glib/dbus-gmain.c | 28 | ||||
| -rw-r--r-- | test/watch.c | 54 | 
19 files changed, 866 insertions, 229 deletions
| @@ -1,3 +1,31 @@ +2003-03-13  Havoc Pennington  <hp@redhat.com> + +	* dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle +	out of memory + +	* dbus/dbus-watch.c (_dbus_watch_list_set_functions): handle out +	of memory + +	* dbus/dbus-connection.h: Make AddWatchFunction and +	AddTimeoutFunction return a bool so they can fail on out-of-memory + +	* bus/bus.c (bus_context_new): set up timeout handlers + +	* bus/connection.c (bus_connections_setup_connection): set up +	timeout handlers + +	* glib/dbus-gmain.c: adapt to the fact that set_functions stuff +	can fail + +	* bus/bus.c (bus_context_new): adapt to changes + +	* bus/connection.c: adapt to changes + +	* test/watch.c: adapt to DBusWatch changes + +	* bus/dispatch.c (bus_dispatch_test): started adding this but +	didn't finish +	  2003-03-14  Anders Carlsson  <andersca@codefactory.se>  	* bus/dispatch.c (send_service_nonexistent_error): Fix typo. diff --git a/bus/Makefile.am b/bus/Makefile.am index f8cff917..9c2f08bd 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -60,7 +60,7 @@ noinst_PROGRAMS=$(TESTS)  bus_test_SOURCES=				\  	test-main.c -bus_test_LDADD= $(top_builddir)/dbus/libdbus-convenience.la libdbus-daemon.la +bus_test_LDADD= $(top_builddir)/dbus/libdbus-1.la libdbus-daemon.la  ## mop up the gcov files  clean-local: @@ -49,12 +49,12 @@ server_watch_callback (DBusWatch     *watch,    dbus_server_handle_watch (context->server, watch, condition);  } -static void +static dbus_bool_t  add_server_watch (DBusWatch  *watch,                    BusContext *context)  { -  bus_loop_add_watch (watch, server_watch_callback, context, -                      NULL); +  return bus_loop_add_watch (watch, server_watch_callback, context, +                             NULL);  }  static void @@ -65,6 +65,27 @@ remove_server_watch (DBusWatch  *watch,  }  static void +server_timeout_callback (DBusTimeout   *timeout, +                         void          *data) +{ +  dbus_timeout_handle (timeout); +} + +static dbus_bool_t +add_server_timeout (DBusTimeout *timeout, +                    BusContext  *context) +{ +  return bus_loop_add_timeout (timeout, server_timeout_callback, context, NULL); +} + +static void +remove_server_timeout (DBusTimeout *timeout, +                       BusContext  *context) +{ +  bus_loop_remove_timeout (timeout, server_timeout_callback, context); +} + +static void  new_connection_callback (DBusServer     *server,                           DBusConnection *new_connection,                           void           *data) @@ -136,11 +157,24 @@ bus_context_new (const char  *address,                                             new_connection_callback,                                             context, NULL); -  dbus_server_set_watch_functions (context->server, -                                   (DBusAddWatchFunction) add_server_watch, -                                   (DBusRemoveWatchFunction) remove_server_watch, -                                   context, -                                   NULL); +  if (!dbus_server_set_watch_functions (context->server, +                                        (DBusAddWatchFunction) add_server_watch, +                                        (DBusRemoveWatchFunction) remove_server_watch, +                                        context, +                                        NULL)) +    { +      BUS_SET_OOM (error); +      goto failed; +    } + +  if (!dbus_server_set_timeout_functions (context->server, +                                          (DBusAddTimeoutFunction) add_server_timeout, +                                          (DBusRemoveTimeoutFunction) remove_server_timeout, +                                          context, NULL)) +    { +      BUS_SET_OOM (error); +      goto failed; +    }    return context; @@ -152,6 +186,22 @@ bus_context_new (const char  *address,  void  bus_context_shutdown (BusContext  *context)  { +  if (context->server == NULL || +      !dbus_server_get_is_connected (context->server)) +    return; +   +  if (!dbus_server_set_watch_functions (context->server, +                                        NULL, NULL, +                                        context, +                                        NULL)) +    _dbus_assert_not_reached ("setting watch functions to NULL failed"); +   +  if (!dbus_server_set_timeout_functions (context->server, +                                          NULL, NULL, +                                          context, +                                          NULL)) +    _dbus_assert_not_reached ("setting timeout functions to NULL failed"); +      dbus_server_disconnect (context->server);  } @@ -170,6 +220,8 @@ bus_context_unref (BusContext *context)    if (context->refcount == 0)      { +      bus_context_shutdown (context); +              if (context->registry)          bus_registry_unref (context->registry);        if (context->connections) diff --git a/bus/connection.c b/bus/connection.c index cdc8be79..f0463392 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -108,11 +108,18 @@ bus_connection_disconnected (DBusConnection *connection)    bus_dispatch_remove_connection (connection);    /* no more watching */ -  dbus_connection_set_watch_functions (connection, -                                       NULL, NULL, -                                       connection, -                                       NULL); - +  if (!dbus_connection_set_watch_functions (connection, +                                            NULL, NULL, +                                            connection, +                                            NULL)) +    _dbus_assert_not_reached ("setting watch functions to NULL failed"); + +  if (!dbus_connection_set_timeout_functions (connection, +                                              NULL, NULL, +                                              connection, +                                              NULL)) +    _dbus_assert_not_reached ("setting timeout functions to NULL failed"); +      bus_connection_remove_transactions (connection);    _dbus_list_remove (&d->connections->list, connection); @@ -140,12 +147,12 @@ connection_watch_callback (DBusWatch     *watch,    dbus_connection_unref (connection);  } -static void +static dbus_bool_t  add_connection_watch (DBusWatch      *watch,                        DBusConnection *connection)  { -  bus_loop_add_watch (watch, connection_watch_callback, connection, -                      NULL); +  return bus_loop_add_watch (watch, connection_watch_callback, connection, +                             NULL);  }  static void @@ -156,6 +163,27 @@ remove_connection_watch (DBusWatch      *watch,  }  static void +connection_timeout_callback (DBusTimeout   *timeout, +                             void          *data) +{ +  dbus_timeout_handle (timeout); +} + +static dbus_bool_t +add_connection_timeout (DBusTimeout    *timeout, +                        DBusConnection *connection) +{ +  return bus_loop_add_timeout (timeout, connection_timeout_callback, connection, NULL); +} + +static void +remove_connection_timeout (DBusTimeout    *timeout, +                           DBusConnection *connection) +{ +  bus_loop_remove_timeout (timeout, connection_timeout_callback, connection); +} + +static void  free_connection_data (void *data)  {    BusConnectionData *d = data; @@ -249,18 +277,35 @@ bus_connections_setup_connection (BusConnections *connections,        dbus_connection_disconnect (connection);        return FALSE;      } - -  dbus_connection_ref (connection); -  dbus_connection_set_watch_functions (connection, -                                       (DBusAddWatchFunction) add_connection_watch, -                                       (DBusRemoveWatchFunction) remove_connection_watch, -                                       connection, -                                       NULL); +  if (!dbus_connection_set_watch_functions (connection, +                                            (DBusAddWatchFunction) add_connection_watch, +                                            (DBusRemoveWatchFunction) remove_connection_watch, +                                            connection, +                                            NULL)) +    { +      dbus_connection_disconnect (connection); +      return FALSE; +    } +   +  if (!dbus_connection_set_timeout_functions (connection, +                                              (DBusAddTimeoutFunction) add_connection_timeout, +                                              (DBusRemoveTimeoutFunction) remove_connection_timeout, +                                              connection, NULL)) +    { +      dbus_connection_disconnect (connection); +      return FALSE; +    } +    /* Setup the connection with the dispatcher */    if (!bus_dispatch_add_connection (connection)) -    return FALSE; +    { +      dbus_connection_disconnect (connection); +      return FALSE; +    } + +  dbus_connection_ref (connection);    return TRUE;  } diff --git a/bus/dispatch.c b/bus/dispatch.c index 59705912..04d68ecc 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -27,6 +27,7 @@  #include "services.h"  #include "utils.h"  #include "bus.h" +#include "test.h"  #include <dbus/dbus-internals.h>  #include <string.h> @@ -142,11 +143,9 @@ send_service_nonexistent_error (BusTransaction *transaction,    return TRUE;  } -static DBusHandlerResult -bus_dispatch_message_handler (DBusMessageHandler *handler, -			      DBusConnection     *connection, -			      DBusMessage        *message, -			      void               *user_data) +static void +bus_dispatch (DBusConnection *connection, +              DBusMessage    *message)  {    const char *sender, *service_name, *message_name;    DBusError error; @@ -313,6 +312,15 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,      }    dbus_connection_unref (connection); +} + +static DBusHandlerResult +bus_dispatch_message_handler (DBusMessageHandler *handler, +			      DBusConnection     *connection, +			      DBusMessage        *message, +			      void               *user_data) +{ +  bus_dispatch (connection, message);    return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;  } @@ -361,3 +369,70 @@ bus_dispatch_remove_connection (DBusConnection *connection)  			    NULL, NULL);  } + + +#ifdef DBUS_BUILD_TESTS + +static void +run_test_bus (BusContext *context) +{ +   +   +} + +static dbus_bool_t +check_hello_message (BusContext     *context, +                     DBusConnection *connection) +{ +  DBusMessage *message; +  dbus_int32_t serial; +   +  message = dbus_message_new (DBUS_SERVICE_DBUS, +			      DBUS_MESSAGE_HELLO); + +  if (message == NULL) +    _dbus_assert_not_reached ("no memory"); + +  if (!dbus_connection_send (connection, message, &serial)) +    _dbus_assert_not_reached ("no memory"); + +  return TRUE; +} + +dbus_bool_t +bus_dispatch_test (const DBusString *test_data_dir) +{ +  BusContext *context; +  DBusError error; +  const char *activation_dirs[] = { NULL, NULL }; +  DBusConnection *foo; +  DBusConnection *bar; +  DBusConnection *baz; +  DBusResultCode result; + +  return TRUE; /* FIXME */ +   +  dbus_error_init (&error); +  context = bus_context_new ("debug:name=test-server", +                             activation_dirs, +                             &error); +  if (context == NULL) +    _dbus_assert_not_reached ("could not alloc context"); +   +  foo = dbus_connection_open ("debug:name=test-server", &result); +  if (foo == NULL) +    _dbus_assert_not_reached ("could not alloc connection"); + +  bar = dbus_connection_open ("debug:name=test-server", &result); +  if (bar == NULL) +    _dbus_assert_not_reached ("could not alloc connection"); + +  baz = dbus_connection_open ("debug:name=test-server", &result); +  if (baz == NULL) +    _dbus_assert_not_reached ("could not alloc connection"); +   +   +   +  return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ @@ -26,20 +26,46 @@  #include <dbus/dbus-list.h>  #include <dbus/dbus-sysdeps.h> -static DBusList *watches = NULL; -static int watch_list_serial = 0; +static DBusList *callbacks = NULL; +static int callback_list_serial = 0; +static int watch_count = 0; +static int timeout_count = 0;  static dbus_bool_t exited = FALSE; +typedef enum +{ +  CALLBACK_WATCH, +  CALLBACK_TIMEOUT +} CallbackType; +  typedef struct  { -  DBusWatch *watch; -  BusWatchFunction function; +  CallbackType type;    void *data;    DBusFreeFunction free_data_func; +} Callback; + +typedef struct +{ +  Callback callback; +  BusWatchFunction function; +  DBusWatch *watch;  } WatchCallback; -dbus_bool_t -bus_loop_add_watch (DBusWatch        *watch, +typedef struct +{ +  Callback callback; +  DBusTimeout *timeout; +  BusTimeoutFunction function; +  unsigned long last_tv_sec; +  unsigned long last_tv_usec; +} TimeoutCallback; + +#define WATCH_CALLBACK(callback)   ((WatchCallback*)callback) +#define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback) + +static WatchCallback* +watch_callback_new (DBusWatch        *watch,                      BusWatchFunction  function,                      void             *data,                      DBusFreeFunction  free_data_func) @@ -48,20 +74,108 @@ bus_loop_add_watch (DBusWatch        *watch,    cb = dbus_new (WatchCallback, 1);    if (cb == NULL) -    return FALSE; +    return NULL;    cb->watch = watch;    cb->function = function; -  cb->data = data; -  cb->free_data_func = free_data_func; +  cb->callback.type = CALLBACK_WATCH; +  cb->callback.data = data; +  cb->callback.free_data_func = free_data_func; + +  return cb; +} -  if (!_dbus_list_append (&watches, cb)) +static TimeoutCallback* +timeout_callback_new (DBusTimeout        *timeout, +                      BusTimeoutFunction  function, +                      void               *data, +                      DBusFreeFunction    free_data_func) +{ +  TimeoutCallback *cb; + +  cb = dbus_new (TimeoutCallback, 1); +  if (cb == NULL) +    return NULL; + +  cb->timeout = timeout; +  cb->function = function; +  _dbus_get_current_time (&cb->last_tv_sec, +                          &cb->last_tv_usec); +  cb->callback.type = CALLBACK_TIMEOUT; +  cb->callback.data = data; +  cb->callback.free_data_func = free_data_func; +   +  return cb; +} + +static void +callback_free (Callback *cb) +{ +  if (cb->free_data_func) +    (* cb->free_data_func) (cb->data); + +  dbus_free (cb); +} + +static dbus_bool_t +add_callback (Callback *cb) +{ +  if (!_dbus_list_append (&callbacks, cb)) +    return FALSE; + +  callback_list_serial += 1; + +  switch (cb->type)      { -      dbus_free (cb); -      return FALSE; +    case CALLBACK_WATCH: +      watch_count += 1; +      break; +    case CALLBACK_TIMEOUT: +      timeout_count += 1; +      break;      } +   +  return TRUE; +} + +static void +remove_callback (DBusList *link) +{ +  Callback *cb = link->data; +   +  switch (cb->type) +    { +    case CALLBACK_WATCH: +      watch_count -= 1; +      break; +    case CALLBACK_TIMEOUT: +      timeout_count -= 1; +      break; +    } +   +  callback_free (cb); +  _dbus_list_remove_link (&callbacks, link); +  callback_list_serial += 1; +} + +dbus_bool_t +bus_loop_add_watch (DBusWatch        *watch, +                    BusWatchFunction  function, +                    void             *data, +                    DBusFreeFunction  free_data_func) +{ +  WatchCallback *wcb; + +  wcb = watch_callback_new (watch, function, data, free_data_func); +  if (wcb == NULL) +    return FALSE; -  watch_list_serial += 1; +  if (!add_callback ((Callback*) wcb)) +    { +      wcb->callback.free_data_func = NULL; /* don't want to have this side effect */ +      callback_free ((Callback*) wcb); +      return FALSE; +    }    return TRUE;  } @@ -73,23 +187,18 @@ bus_loop_remove_watch (DBusWatch        *watch,  {    DBusList *link; -  link = _dbus_list_get_first_link (&watches); +  link = _dbus_list_get_first_link (&callbacks);    while (link != NULL)      { -      DBusList *next = _dbus_list_get_next_link (&watches, link); -      WatchCallback *cb = link->data; +      DBusList *next = _dbus_list_get_next_link (&callbacks, link); +      Callback *this = link->data; -      if (cb->watch == watch && -          cb->function == function && -          cb->data == data) +      if (this->type == CALLBACK_WATCH && +          WATCH_CALLBACK (this)->watch == watch && +          this->data == data && +          WATCH_CALLBACK (this)->function == function)          { -          _dbus_list_remove_link (&watches, link); - -          watch_list_serial += 1; -           -          if (cb->free_data_func) -            (* cb->free_data_func) (cb->data); -          dbus_free (cb); +          remove_callback (link);            return;          } @@ -101,6 +210,58 @@ bus_loop_remove_watch (DBusWatch        *watch,                watch, function, data);  } +dbus_bool_t +bus_loop_add_timeout (DBusTimeout        *timeout, +                      BusTimeoutFunction  function, +                      void               *data, +                      DBusFreeFunction    free_data_func) +{ +  TimeoutCallback *tcb; + +  tcb = timeout_callback_new (timeout, function, data, free_data_func); +  if (tcb == NULL) +    return FALSE; + +  if (!add_callback ((Callback*) tcb)) +    { +      tcb->callback.free_data_func = NULL; /* don't want to have this side effect */ +      callback_free ((Callback*) tcb); +      return FALSE; +    } +   +  return TRUE; +} + +void +bus_loop_remove_timeout (DBusTimeout        *timeout, +                         BusTimeoutFunction  function, +                         void               *data) +{ +  DBusList *link; +   +  link = _dbus_list_get_first_link (&callbacks); +  while (link != NULL) +    { +      DBusList *next = _dbus_list_get_next_link (&callbacks, link); +      Callback *this = link->data; + +      if (this->type == CALLBACK_TIMEOUT && +          TIMEOUT_CALLBACK (this)->timeout == timeout && +          this->data == data && +          TIMEOUT_CALLBACK (this)->function == function) +        { +          remove_callback (link); +           +          return; +        } +       +      link = next; +    } + +  _dbus_warn ("could not find timeout %p function %p data %p to remove\n", +              timeout, function, data); +} +  void  bus_loop_run (void)  { @@ -113,59 +274,187 @@ bus_loop_run (void)        DBusList *link;        int n_ready;        int initial_serial; +      long timeout;        fds = NULL;        watches_for_fds = NULL; -      n_fds = _dbus_list_get_length (&watches); - -      if (n_fds == 0) +      if (callbacks == NULL)          {            bus_loop_quit ();            goto next_iteration;          } -      fds = dbus_new0 (DBusPollFD, n_fds); -      while (fds == NULL) +      n_fds = watch_count; + +      if (n_fds > 0)          { -          bus_wait_for_memory ();            fds = dbus_new0 (DBusPollFD, n_fds); +          while (fds == NULL) +            { +              bus_wait_for_memory (); +              fds = dbus_new0 (DBusPollFD, n_fds); +            } +           +          watches_for_fds = dbus_new (WatchCallback*, n_fds); +          while (watches_for_fds == NULL) +            { +              bus_wait_for_memory (); +              watches_for_fds = dbus_new (WatchCallback*, n_fds); +            } +       +          i = 0; +          link = _dbus_list_get_first_link (&callbacks); +          while (link != NULL) +            { +              DBusList *next = _dbus_list_get_next_link (&callbacks, link); +              Callback *cb = link->data; +              if (cb->type == CALLBACK_WATCH) +                { +                  unsigned int flags; +                  WatchCallback *wcb = WATCH_CALLBACK (cb); +                   +                  watches_for_fds[i] = wcb; +                   +                  flags = dbus_watch_get_flags (wcb->watch); +                   +                  fds[i].fd = dbus_watch_get_fd (wcb->watch); +                  if (flags & DBUS_WATCH_READABLE) +                    fds[i].events |= _DBUS_POLLIN; +                  if (flags & DBUS_WATCH_WRITABLE) +                    fds[i].events |= _DBUS_POLLOUT; + +                  ++i; +                } +               +              link = next; +            } + +          _dbus_assert (i == n_fds);          } -      watches_for_fds = dbus_new (WatchCallback*, n_fds); -      while (watches_for_fds == NULL) +      timeout = -1; +      if (timeout_count > 0)          { -          bus_wait_for_memory (); -          watches_for_fds = dbus_new (WatchCallback*, n_fds); +          unsigned long tv_sec; +          unsigned long tv_usec; +           +          _dbus_get_current_time (&tv_sec, &tv_usec); +           +          link = _dbus_list_get_first_link (&callbacks); +          while (link != NULL) +            { +              DBusList *next = _dbus_list_get_next_link (&callbacks, link); +              Callback *cb = link->data; + +              if (cb->type == CALLBACK_TIMEOUT) +                { +                  TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); +                  unsigned long interval; +                  unsigned long elapsed; + +                  if (tcb->last_tv_sec > tv_sec || +                      (tcb->last_tv_sec == tv_sec && +                       tcb->last_tv_usec > tv_usec)) +                    { +                      /* Clock went backward, pretend timeout +                       * was just installed. +                       */ +                      tcb->last_tv_sec = tv_sec; +                      tcb->last_tv_usec = tv_usec; +                      _dbus_verbose ("System clock went backward\n"); +                    } +                   +                  interval = dbus_timeout_get_interval (tcb->timeout); + +                  elapsed = +                    (tv_sec - tcb->last_tv_sec) * 1000 + +                    (tv_usec - tcb->last_tv_usec) / 1000; + +                  if (interval < elapsed) +                    timeout = 0; +                  else if (timeout < 0) +                    timeout = interval - elapsed; +                  else +                    timeout = MIN (((unsigned long)timeout), interval - elapsed); + +                  _dbus_assert (timeout >= 0); +                   +                  if (timeout == 0) +                    break; /* it's not going to get shorter... */ +                } +               +              link = next; +            }          } -      i = 0; -      link = _dbus_list_get_first_link (&watches); -      while (link != NULL) +      n_ready = _dbus_poll (fds, n_fds, timeout); + +      initial_serial = callback_list_serial; + +      if (timeout_count > 0)          { -          DBusList *next = _dbus_list_get_next_link (&watches, link); -          WatchCallback *cb = link->data; -          int flags; -           -          watches_for_fds[i] = cb; +          unsigned long tv_sec; +          unsigned long tv_usec; -          flags = dbus_watch_get_flags (cb->watch); -           -          fds[i].fd = dbus_watch_get_fd (cb->watch); -          if (flags & DBUS_WATCH_READABLE) -            fds[i].events |= _DBUS_POLLIN; -          if (flags & DBUS_WATCH_WRITABLE) -            fds[i].events |= _DBUS_POLLOUT; -           -          link = next; -          ++i; -        } +          _dbus_get_current_time (&tv_sec, &tv_usec); + +          /* It'd be nice to avoid this O(n) thingy here */ +          link = _dbus_list_get_first_link (&callbacks); +          while (link != NULL) +            { +              DBusList *next = _dbus_list_get_next_link (&callbacks, link); +              Callback *cb = link->data; + +              if (initial_serial != callback_list_serial) +                goto next_iteration; + +              if (exited) +                goto next_iteration; +               +              if (cb->type == CALLBACK_TIMEOUT) +                { +                  TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); +                  unsigned long interval; +                  unsigned long elapsed; +                   +                  if (tcb->last_tv_sec > tv_sec || +                      (tcb->last_tv_sec == tv_sec && +                       tcb->last_tv_usec > tv_usec)) +                    { +                      /* Clock went backward, pretend timeout +                       * was just installed. +                       */ +                      tcb->last_tv_sec = tv_sec; +                      tcb->last_tv_usec = tv_usec; +                      _dbus_verbose ("System clock went backward\n"); +                      goto next_timeout; +                    } +                   +                  interval = dbus_timeout_get_interval (tcb->timeout); -      n_ready = _dbus_poll (fds, n_fds, -1); +                  elapsed = +                    (tv_sec - tcb->last_tv_sec) * 1000 + +                    (tv_usec - tcb->last_tv_usec) / 1000; +                  if (interval <= elapsed) +                    { +                      /* Save last callback time and fire this timeout */ +                      tcb->last_tv_sec = tv_sec; +                      tcb->last_tv_usec = tv_usec; +                       +                      (* tcb->function) (tcb->timeout, +                                         cb->data); +                    } +                } + +            next_timeout: +              link = next; +            } +        } +              if (n_ready > 0)          { -          initial_serial = watch_list_serial;            i = 0;            while (i < n_fds)              { @@ -173,7 +462,7 @@ bus_loop_run (void)                 * approach could result in starving watches                 * toward the end of the list.                 */ -              if (initial_serial != watch_list_serial) +              if (initial_serial != callback_list_serial)                  goto next_iteration;                if (exited) @@ -181,10 +470,10 @@ bus_loop_run (void)                if (fds[i].revents != 0)                  { -                  WatchCallback *cb; +                  WatchCallback *wcb;                    unsigned int condition; -                  cb = watches_for_fds[i]; +                  wcb = watches_for_fds[i];                    condition = 0;                    if (fds[i].revents & _DBUS_POLLIN) @@ -201,9 +490,9 @@ bus_loop_run (void)                     */                    if (condition != 0) -                    (* cb->function) (cb->watch, -                                      condition, -                                      cb->data); +                    (* wcb->function) (wcb->watch, +                                       condition, +                                       ((Callback*)wcb)->data);                  }                ++i; @@ -26,19 +26,29 @@  #include <dbus/dbus.h> -typedef void (* BusWatchFunction) (DBusWatch     *watch, -                                   unsigned int   condition, -                                   void          *data); +typedef void (* BusWatchFunction)   (DBusWatch     *watch, +                                     unsigned int   condition, +                                     void          *data); +typedef void (* BusTimeoutFunction) (DBusTimeout   *timeout, +                                     void          *data); + +dbus_bool_t bus_loop_add_watch      (DBusWatch          *watch, +                                     BusWatchFunction    function, +                                     void               *data, +                                     DBusFreeFunction    free_data_func); +void        bus_loop_remove_watch   (DBusWatch          *watch, +                                     BusWatchFunction    function, +                                     void               *data); +dbus_bool_t bus_loop_add_timeout    (DBusTimeout        *timeout, +                                     BusTimeoutFunction  function, +                                     void               *data, +                                     DBusFreeFunction    free_data_func); +void        bus_loop_remove_timeout (DBusTimeout        *timeout, +                                     BusTimeoutFunction  function, +                                     void               *data); +void        bus_loop_run            (void); +void        bus_loop_quit           (void); -dbus_bool_t bus_loop_add_watch    (DBusWatch        *watch, -                                   BusWatchFunction  function, -                                   void             *data, -                                   DBusFreeFunction  free_data_func); -void        bus_loop_remove_watch (DBusWatch        *watch, -                                   BusWatchFunction  function, -                                   void             *data); -void        bus_loop_run          (void); -void        bus_loop_quit         (void);  #endif /* BUS_LOOP_H */ diff --git a/bus/test-main.c b/bus/test-main.c index 27c06f48..503d996d 100644 --- a/bus/test-main.c +++ b/bus/test-main.c @@ -22,16 +22,41 @@   */  #include "test.h" +#include <stdio.h> +#include <stdlib.h> +#include <dbus/dbus-string.h> +#include <dbus/dbus-sysdeps.h> + +static void +die (const char *failure) +{ +  fprintf (stderr, "Unit test failed: %s\n", failure); +  exit (1); +}  int  main (int argc, char **argv)  {  #ifdef DBUS_BUILD_TESTS +  const char *dir; +  DBusString test_data_dir; + +  if (argc > 1) +    dir = argv[1]; +  else +    dir = _dbus_getenv ("DBUS_TEST_DATA"); + +  if (dir == NULL) +    dir = ""; +  _dbus_string_init_const (&test_data_dir, dir); +  if (!bus_dispatch_test (&test_data_dir)) +    die ("dispatch");    return 0;  #else /* DBUS_BUILD_TESTS */ +          return 0;  #endif  } @@ -31,7 +31,7 @@  #include <dbus/dbus.h>  #include <dbus/dbus-string.h> -dbus_bool_t bus_test_foo (const DBusString *test_data_dir); +dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir);  #endif diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index bfc27e2a..19fe717d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1810,31 +1810,44 @@ dbus_connection_dispatch_message (DBusConnection *connection)   *    * It is not allowed to reference a DBusWatch after it has been passed   * to remove_function. + * + * If #FALSE is returned due to lack of memory, the failure may be due + * to a #FALSE return from the new add_function. If so, the + * add_function may have been called successfully one or more times, + * but the remove_function will also have been called to remove any + * successful adds. i.e. if #FALSE is returned the net result + * should be that dbus_connection_set_watch_functions() has no effect, + * but the add_function and remove_function may have been called.   *    * @param connection the connection.   * @param add_function function to begin monitoring a new descriptor.   * @param remove_function function to stop monitoring a descriptor.   * @param data data to pass to add_function and remove_function.   * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory)   */ -void +dbus_bool_t  dbus_connection_set_watch_functions (DBusConnection              *connection,                                       DBusAddWatchFunction         add_function,                                       DBusRemoveWatchFunction      remove_function,                                       void                        *data,                                       DBusFreeFunction             free_data_function)  { +  dbus_bool_t retval; +      dbus_mutex_lock (connection->mutex);    /* ref connection for slightly better reentrancy */    _dbus_connection_ref_unlocked (connection); -  _dbus_watch_list_set_functions (connection->watches, -                                  add_function, remove_function, -                                  data, free_data_function); +  retval = _dbus_watch_list_set_functions (connection->watches, +                                           add_function, remove_function, +                                           data, free_data_function);    dbus_mutex_unlock (connection->mutex);    /* drop our paranoid refcount */    dbus_connection_unref (connection); + +  return retval;  }  /** @@ -1855,25 +1868,30 @@ dbus_connection_set_watch_functions (DBusConnection              *connection,   * @param remove_function function to remove a timeout.   * @param data data to pass to add_function and remove_function.   * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory)   */ -void +dbus_bool_t  dbus_connection_set_timeout_functions   (DBusConnection            *connection,  					 DBusAddTimeoutFunction     add_function,  					 DBusRemoveTimeoutFunction  remove_function,  					 void                      *data,  					 DBusFreeFunction           free_data_function)  { +  dbus_bool_t retval; +      dbus_mutex_lock (connection->mutex);    /* ref connection for slightly better reentrancy */    _dbus_connection_ref_unlocked (connection); -  _dbus_timeout_list_set_functions (connection->timeouts, -				    add_function, remove_function, -				    data, free_data_function); +  retval = _dbus_timeout_list_set_functions (connection->timeouts, +                                             add_function, remove_function, +                                             data, free_data_function);    dbus_mutex_unlock (connection->mutex);    /* drop our paranoid refcount */ -  dbus_connection_unref (connection);   +  dbus_connection_unref (connection); + +  return retval;  }  /** diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index 6b480136..bf0983e6 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -56,17 +56,15 @@ typedef enum                                   *   can be present in current state). */  } DBusWatchFlags; -typedef void (* DBusAddWatchFunction)      (DBusWatch      *watch, -					    void           *data); - -typedef void (* DBusRemoveWatchFunction)   (DBusWatch      *watch, -					    void           *data); - -typedef void (* DBusWakeupMainFunction)    (void           *data); -typedef void (* DBusAddTimeoutFunction)    (DBusTimeout    *timeout, -					    void           *data); -typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout    *timeout, -					    void           *data); +typedef dbus_bool_t (* DBusAddWatchFunction)      (DBusWatch      *watch, +                                                   void           *data); +typedef void        (* DBusRemoveWatchFunction)   (DBusWatch      *watch, +                                                   void           *data); +typedef void        (* DBusWakeupMainFunction)    (void           *data); +typedef dbus_bool_t (* DBusAddTimeoutFunction)    (DBusTimeout    *timeout, +                                                   void           *data); +typedef void        (* DBusRemoveTimeoutFunction) (DBusTimeout    *timeout, +                                                   void           *data);  DBusConnection* dbus_connection_open                   (const char     *address,  							DBusResultCode *result); @@ -99,24 +97,24 @@ DBusMessage *dbus_connection_send_with_reply_and_block (DBusConnection     *conn                                                          DBusError          *error); +dbus_bool_t dbus_connection_set_watch_functions      (DBusConnection            *connection, +                                                      DBusAddWatchFunction       add_function, +                                                      DBusRemoveWatchFunction    remove_function, +                                                      void                      *data, +                                                      DBusFreeFunction           free_data_function); +dbus_bool_t dbus_connection_set_timeout_functions    (DBusConnection            *connection, +                                                      DBusAddTimeoutFunction     add_function, +                                                      DBusRemoveTimeoutFunction  remove_function, +                                                      void                      *data, +                                                      DBusFreeFunction           free_data_function); +void        dbus_connection_set_wakeup_main_function (DBusConnection            *connection, +                                                      DBusWakeupMainFunction     wakeup_main_function, +                                                      void                      *data, +                                                      DBusFreeFunction           free_data_function); +void        dbus_connection_handle_watch             (DBusConnection            *connection, +                                                      DBusWatch                 *watch, +                                                      unsigned int               condition); -void dbus_connection_set_watch_functions      (DBusConnection            *connection, -					       DBusAddWatchFunction       add_function, -					       DBusRemoveWatchFunction    remove_function, -					       void                      *data, -					       DBusFreeFunction           free_data_function); -void dbus_connection_set_timeout_functions    (DBusConnection            *connection, -					       DBusAddTimeoutFunction     add_function, -					       DBusRemoveTimeoutFunction  remove_function, -					       void                      *data, -					       DBusFreeFunction           free_data_function); -void dbus_connection_set_wakeup_main_function (DBusConnection            *connection, -					       DBusWakeupMainFunction     wakeup_main_function, -					       void                      *data, -					       DBusFreeFunction           free_data_function); -void dbus_connection_handle_watch             (DBusConnection            *connection, -					       DBusWatch                 *watch, -					       unsigned int               condition); diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 0065e510..99a5a2af 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -392,19 +392,20 @@ dbus_server_set_new_connection_function (DBusServer                *server,   * @param remove_function function to stop monitoring a descriptor.   * @param data data to pass to add_function and remove_function.   * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory)   */ -void +dbus_bool_t  dbus_server_set_watch_functions (DBusServer              *server,                                   DBusAddWatchFunction     add_function,                                   DBusRemoveWatchFunction  remove_function,                                   void                    *data,                                   DBusFreeFunction         free_data_function)  { -  _dbus_watch_list_set_functions (server->watches, -                                  add_function, -                                  remove_function, -                                  data, -                                  free_data_function); +  return _dbus_watch_list_set_functions (server->watches, +                                         add_function, +                                         remove_function, +                                         data, +                                         free_data_function);  }  /** @@ -419,17 +420,18 @@ dbus_server_set_watch_functions (DBusServer              *server,   * @param remove_function function to remove a timeout.   * @param data data to pass to add_function and remove_function.   * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory)   */ -void +dbus_bool_t  dbus_server_set_timeout_functions (DBusServer                *server,  				   DBusAddTimeoutFunction     add_function,  				   DBusRemoveTimeoutFunction  remove_function,  				   void                      *data,  				   DBusFreeFunction           free_data_function)  { -  _dbus_timeout_list_set_functions (server->timeouts, -				    add_function, remove_function, -				    data, free_data_function);  +  return _dbus_timeout_list_set_functions (server->timeouts, +                                           add_function, remove_function, +                                           data, free_data_function);   }  /** diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h index fc3a57e7..6665335b 100644 --- a/dbus/dbus-server.h +++ b/dbus/dbus-server.h @@ -45,31 +45,28 @@ void        dbus_server_ref              (DBusServer     *server);  void        dbus_server_unref            (DBusServer     *server);  void        dbus_server_disconnect       (DBusServer     *server);  dbus_bool_t dbus_server_get_is_connected (DBusServer     *server); +void        dbus_server_set_new_connection_function (DBusServer                *server, +                                                     DBusNewConnectionFunction  function, +                                                     void                      *data, +                                                     DBusFreeFunction           free_data_function); +dbus_bool_t dbus_server_set_watch_functions         (DBusServer                *server, +                                                     DBusAddWatchFunction       add_function, +                                                     DBusRemoveWatchFunction    remove_function, +                                                     void                      *data, +                                                     DBusFreeFunction           free_data_function); +dbus_bool_t dbus_server_set_timeout_functions       (DBusServer                *server, +                                                     DBusAddTimeoutFunction     add_function, +                                                     DBusRemoveTimeoutFunction  remove_function, +                                                     void                      *data, +                                                     DBusFreeFunction           free_data_function); +void        dbus_server_handle_watch                (DBusServer                *server, +                                                     DBusWatch                 *watch, +                                                     unsigned int               condition); +void        dbus_server_set_max_connections         (DBusServer                *server, +                                                     int                        max_connections); +int         dbus_server_get_max_connections         (DBusServer                *server); +int         dbus_server_get_n_connections           (DBusServer                *server); -void dbus_server_set_new_connection_function (DBusServer                *server, -                                              DBusNewConnectionFunction  function, -                                              void                      *data, -                                              DBusFreeFunction           free_data_function); -void dbus_server_set_watch_functions         (DBusServer                *server, -                                              DBusAddWatchFunction       add_function, -                                              DBusRemoveWatchFunction    remove_function, -                                              void                      *data, -                                              DBusFreeFunction           free_data_function); -void dbus_server_set_timeout_functions       (DBusServer                *server, -					      DBusAddTimeoutFunction     add_function, -					      DBusRemoveTimeoutFunction  remove_function, -					      void                      *data, -					      DBusFreeFunction           free_data_function); -void dbus_server_handle_watch                (DBusServer                *server, -                                              DBusWatch                 *watch, -                                              unsigned int               condition); - - -void dbus_server_set_max_connections         (DBusServer                *server, -                                              int                        max_connections); -int  dbus_server_get_max_connections         (DBusServer                *server); - -int  dbus_server_get_n_connections           (DBusServer                *server);  int         dbus_server_allocate_data_slot (void);  void        dbus_server_free_data_slot     (int               slot); diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c index 379aeee3..408de422 100644 --- a/dbus/dbus-timeout.c +++ b/dbus/dbus-timeout.c @@ -181,15 +181,50 @@ _dbus_timeout_list_free (DBusTimeoutList *timeout_list)   * @param remove_function the remove timeout function.   * @param data the data for those functions.   * @param free_data_function the function to free the data. + * @returns #FALSE if no memory   *   */ -void +dbus_bool_t  _dbus_timeout_list_set_functions (DBusTimeoutList           *timeout_list,  				  DBusAddTimeoutFunction     add_function,  				  DBusRemoveTimeoutFunction  remove_function,  				  void                      *data,  				  DBusFreeFunction           free_data_function)  { +  /* Add timeouts with the new function, failing on OOM */ +  if (add_function != NULL) +    { +      DBusList *link; +       +      link = _dbus_list_get_first_link (&timeout_list->timeouts); +      while (link != NULL) +        { +          DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, +                                                     link); +       +          if (!(* add_function) (link->data, data)) +            { +              /* remove it all again and return FALSE */ +              DBusList *link2; +               +              link2 = _dbus_list_get_first_link (&timeout_list->timeouts); +              while (link2 != link) +                { +                  DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, +                                                             link2); + +                  (* remove_function) (link2->data, data); +                   +                  link2 = next; +                } + +              return FALSE; +            } +       +          link = next; +        } +    } +      /* Remove all current timeouts from previous timeout handlers */    if (timeout_list->remove_timeout_function != NULL) @@ -207,13 +242,7 @@ _dbus_timeout_list_set_functions (DBusTimeoutList           *timeout_list,    timeout_list->timeout_data = data;    timeout_list->timeout_free_data_function = free_data_function; -  /* Re-add all pending timeouts */ -  if (timeout_list->add_timeout_function != NULL) -    { -      _dbus_list_foreach (&timeout_list->timeouts, -			  (DBusForeachFunction) timeout_list->add_timeout_function, -			  timeout_list->timeout_data); -    } +  return TRUE;  }  /** @@ -234,14 +263,21 @@ _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,    _dbus_timeout_ref (timeout);    if (timeout_list->add_timeout_function != NULL) -    (* timeout_list->add_timeout_function) (timeout, -					    timeout_list->timeout_data); +    { +      if (!(* timeout_list->add_timeout_function) (timeout, +                                                   timeout_list->timeout_data)) +        { +          _dbus_list_remove_last (&timeout_list->timeouts, timeout); +          _dbus_timeout_unref (timeout); +          return FALSE; +        } +    }    return TRUE;  }  /** - * Removes a timeout from the watch list, invoking the + * Removes a timeout from the timeout list, invoking the   * application's DBusRemoveTimeoutFunction if appropriate.   *   * @param timeout_list the timeout list. diff --git a/dbus/dbus-timeout.h b/dbus/dbus-timeout.h index b596bfa1..9de12e8f 100644 --- a/dbus/dbus-timeout.h +++ b/dbus/dbus-timeout.h @@ -44,7 +44,7 @@ void         _dbus_timeout_unref (DBusTimeout        *timeout);  DBusTimeoutList *_dbus_timeout_list_new            (void);  void             _dbus_timeout_list_free           (DBusTimeoutList           *timeout_list); -void             _dbus_timeout_list_set_functions  (DBusTimeoutList           *timeout_list, +dbus_bool_t      _dbus_timeout_list_set_functions  (DBusTimeoutList           *timeout_list,  						    DBusAddTimeoutFunction     add_function,  						    DBusRemoveTimeoutFunction  remove_function,  						    void                      *data, diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c index 681da939..ef2a0ed9 100644 --- a/dbus/dbus-watch.c +++ b/dbus/dbus-watch.c @@ -159,7 +159,7 @@ struct DBusWatchList    DBusList *watches;           /**< Watch objects. */    DBusAddWatchFunction add_watch_function;    /**< Callback for adding a watch. */ -  DBusAddWatchFunction remove_watch_function; /**< Callback for removing a watch. */ +  DBusRemoveWatchFunction remove_watch_function; /**< Callback for removing a watch. */    void *watch_data;                           /**< Data for watch callbacks */    DBusFreeFunction watch_free_data_function;  /**< Free function for watch callback data */  }; @@ -212,15 +212,50 @@ _dbus_watch_list_free (DBusWatchList *watch_list)   * @param remove_function the remove watch function.   * @param data the data for those functions.   * @param free_data_function the function to free the data. + * @returns #FALSE if not enough memory   *   */ -void +dbus_bool_t  _dbus_watch_list_set_functions (DBusWatchList           *watch_list,                                  DBusAddWatchFunction     add_function,                                  DBusRemoveWatchFunction  remove_function,                                  void                    *data,                                  DBusFreeFunction         free_data_function)  { +  /* Add watches with the new watch function, failing on OOM */ +  if (add_function != NULL) +    { +      DBusList *link; +       +      link = _dbus_list_get_first_link (&watch_list->watches); +      while (link != NULL) +        { +          DBusList *next = _dbus_list_get_next_link (&watch_list->watches, +                                                     link); +       +          if (!(* add_function) (link->data, data)) +            { +              /* remove it all again and return FALSE */ +              DBusList *link2; +               +              link2 = _dbus_list_get_first_link (&watch_list->watches); +              while (link2 != link) +                { +                  DBusList *next = _dbus_list_get_next_link (&watch_list->watches, +                                                             link2); + +                  (* remove_function) (link2->data, data); +                   +                  link2 = next; +                } + +              return FALSE; +            } +       +          link = next; +        } +    } +      /* Remove all current watches from previous watch handlers */    if (watch_list->remove_watch_function != NULL) @@ -238,13 +273,7 @@ _dbus_watch_list_set_functions (DBusWatchList           *watch_list,    watch_list->watch_data = data;    watch_list->watch_free_data_function = free_data_function; -  /* Re-add all pending watches */ -  if (watch_list->add_watch_function != NULL) -    { -      _dbus_list_foreach (&watch_list->watches, -                          (DBusForeachFunction) watch_list->add_watch_function, -                          watch_list->watch_data); -    } +  return TRUE;  }  /** @@ -265,8 +294,15 @@ _dbus_watch_list_add_watch (DBusWatchList *watch_list,    _dbus_watch_ref (watch);    if (watch_list->add_watch_function != NULL) -    (* watch_list->add_watch_function) (watch, -                                        watch_list->watch_data); +    { +      if (!(* watch_list->add_watch_function) (watch, +                                               watch_list->watch_data)) +        { +          _dbus_list_remove_last (&watch_list->watches, watch); +          _dbus_watch_unref (watch); +          return FALSE; +        } +    }    return TRUE;  } diff --git a/dbus/dbus-watch.h b/dbus/dbus-watch.h index 869605ae..9d85737e 100644 --- a/dbus/dbus-watch.h +++ b/dbus/dbus-watch.h @@ -43,7 +43,7 @@ void       _dbus_watch_sanitize_condition (DBusWatch *watch,  DBusWatchList* _dbus_watch_list_new           (void);  void           _dbus_watch_list_free          (DBusWatchList           *watch_list); -void           _dbus_watch_list_set_functions (DBusWatchList           *watch_list, +dbus_bool_t    _dbus_watch_list_set_functions (DBusWatchList           *watch_list,                                                 DBusAddWatchFunction     add_function,                                                 DBusRemoveWatchFunction  remove_function,                                                 void                    *data, diff --git a/glib/dbus-gmain.c b/glib/dbus-gmain.c index 40523738..b0ec7c4b 100644 --- a/glib/dbus-gmain.c +++ b/glib/dbus-gmain.c @@ -231,7 +231,7 @@ dbus_server_dispatch (GSource     *source,    return TRUE;  } -static void +static dbus_bool_t  add_watch (DBusWatch *watch,  	   gpointer   data)  { @@ -257,6 +257,8 @@ add_watch (DBusWatch *watch,    dbus_source->poll_fds = g_list_prepend (dbus_source->poll_fds, poll_fd);    g_hash_table_insert (dbus_source->watches, poll_fd, watch); + +  return TRUE;  }  static void @@ -285,7 +287,7 @@ timeout_handler (gpointer data)    return FALSE;  } -static void +static dbus_bool_t  add_timeout (DBusTimeout *timeout,  	     void        *data)  { @@ -295,6 +297,8 @@ add_timeout (DBusTimeout *timeout,  			       timeout_handler, timeout);    dbus_timeout_set_data (timeout, GUINT_TO_POINTER (timeout_tag), NULL); + +  return TRUE;  }  static void @@ -356,16 +360,18 @@ dbus_connection_setup_with_g_main (DBusConnection *connection)    source = create_source (connection, &dbus_connection_funcs); -  dbus_connection_set_watch_functions (connection, -                                       add_watch, -                                       remove_watch, -                                       source, NULL); +  if (!dbus_connection_set_watch_functions (connection, +                                            add_watch, +                                            remove_watch, +                                            source, NULL)) +    goto nomem; -  dbus_connection_set_timeout_functions (connection, -                                         add_timeout, -                                         remove_timeout, -                                         NULL, NULL); -       +  if (!dbus_connection_set_timeout_functions (connection, +                                              add_timeout, +                                              remove_timeout, +                                              NULL, NULL)) +    goto nomem; +        dbus_connection_set_wakeup_main_function (connection,  					    wakeup_main,  					    NULL, NULL); diff --git a/test/watch.c b/test/watch.c index d8e91b78..73f5e97d 100644 --- a/test/watch.c +++ b/test/watch.c @@ -45,19 +45,26 @@ free_watch_data (void *data)    dbus_free (wd);  } -static void +static dbus_bool_t  add_connection_watch (DBusWatch      *watch,                        DBusConnection *connection)  {    WatchData *wd; +  if (!_dbus_list_append (&watches, watch)) +    return FALSE; +      wd = dbus_new0 (WatchData, 1); +  if (wd == NULL) +    { +      _dbus_list_remove_last (&watches, watch); +      return FALSE; +    }      wd->type = WATCH_CONNECTION;    wd->data = connection; -  dbus_connection_ref (connection); -   -  _dbus_list_append (&watches, watch); +  dbus_connection_ref (connection);   +    dbus_watch_set_data (watch, wd, free_watch_data);    watch_list_serial += 1; @@ -67,6 +74,8 @@ add_connection_watch (DBusWatch      *watch,            dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",            dbus_watch_get_fd (watch));  #endif + +  return TRUE;   }  static void @@ -86,19 +95,26 @@ remove_connection_watch (DBusWatch      *watch,  #endif  } -static void +static dbus_bool_t  add_server_watch (DBusWatch      *watch,                    DBusServer     *server)  {    WatchData *wd; +  if (!_dbus_list_append (&watches, watch)) +    return FALSE; +      wd = dbus_new0 (WatchData, 1); +  if (wd == NULL) +    { +      _dbus_list_remove_last (&watches, watch); +      return FALSE; +    } +      wd->type = WATCH_SERVER;    wd->data = server;    dbus_server_ref (server); -   -  _dbus_list_append (&watches, watch);    dbus_watch_set_data (watch, wd, free_watch_data); @@ -109,6 +125,8 @@ add_server_watch (DBusWatch      *watch,            dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",            dbus_watch_get_fd (watch));  #endif + +  return TRUE;  }  static void @@ -324,11 +342,12 @@ quit_mainloop (void)  void  setup_connection (DBusConnection *connection)  { -  dbus_connection_set_watch_functions (connection, -                                       (DBusAddWatchFunction) add_connection_watch, -                                       (DBusRemoveWatchFunction) remove_connection_watch, -                                       connection, -                                       NULL); +  if (!dbus_connection_set_watch_functions (connection, +                                            (DBusAddWatchFunction) add_connection_watch, +                                            (DBusRemoveWatchFunction) remove_connection_watch, +                                            connection, +                                            NULL)) +    _dbus_assert_not_reached ("not enough memory");    dbus_connection_ref (connection);    _dbus_list_append (&connections, connection); @@ -337,9 +356,10 @@ setup_connection (DBusConnection *connection)  void  setup_server (DBusServer *server)  { -  dbus_server_set_watch_functions (server, -                                   (DBusAddWatchFunction) add_server_watch, -                                   (DBusRemoveWatchFunction) remove_server_watch, -                                   server, -                                   NULL); +  if (!dbus_server_set_watch_functions (server, +                                        (DBusAddWatchFunction) add_server_watch, +                                        (DBusRemoveWatchFunction) remove_server_watch, +                                        server, +                                        NULL)) +    _dbus_assert_not_reached ("not enough memory");  } | 
