Commit df008ef9 authored by Havoc Pennington's avatar Havoc Pennington

2003-04-06 Havoc Pennington <hp@pobox.com>

	* dbus/Makefile.am: split lists of sources into stuff that goes in
	the library, util functions that go in the lib and are also used
	elsewhere, and util functions that are used in tests/daemon but
	don't go in the lib.

	* dbus/dbus-mainloop.h, dbus/dbus-mainloop.c: move bus/loop.[hc]
	here so it can be used in test binaries also
parent 856361ff
2003-04-06 Havoc Pennington <hp@pobox.com>
* dbus/Makefile.am: split lists of sources into stuff that goes in
the library, util functions that go in the lib and are also used
elsewhere, and util functions that are used in tests/daemon but
don't go in the lib.
* dbus/dbus-mainloop.h, dbus/dbus-mainloop.c: move bus/loop.[hc]
here so it can be used in test binaries also
2003-04-06 Havoc Pennington <hp@pobox.com>
* dbus/dbus-sysdeps.c (_dbus_become_daemon): write the pidfile
......
......@@ -40,8 +40,6 @@ BUS_SOURCES= \
dispatch.h \
driver.c \
driver.h \
loop.c \
loop.h \
policy.c \
policy.h \
services.c \
......
......@@ -90,7 +90,7 @@ handle_timeout_callback (DBusTimeout *timeout,
BusPendingActivation *pending_activation = data;
while (!dbus_timeout_handle (pending_activation->timeout))
bus_wait_for_memory ();
_dbus_wait_for_memory ();
}
static void
......@@ -103,9 +103,9 @@ bus_pending_activation_free (BusPendingActivation *pending_activation)
if (pending_activation->timeout_added)
{
bus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
pending_activation->timeout,
handle_timeout_callback, pending_activation);
_dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
pending_activation->timeout,
handle_timeout_callback, pending_activation);
pending_activation->timeout_added = FALSE;
}
......@@ -604,7 +604,7 @@ pending_activation_failed (BusPendingActivation *pending_activation,
{
/* FIXME use preallocated OOM messages instead of bus_wait_for_memory() */
while (!try_send_activation_failure (pending_activation, how))
bus_wait_for_memory ();
_dbus_wait_for_memory ();
/* Destroy this pending activation */
_dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
......@@ -650,9 +650,9 @@ add_babysitter_watch (DBusWatch *watch,
{
BusPendingActivation *pending_activation = data;
return bus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
watch, babysitter_watch_callback, pending_activation,
NULL);
return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
watch, babysitter_watch_callback, pending_activation,
NULL);
}
static void
......@@ -661,8 +661,8 @@ remove_babysitter_watch (DBusWatch *watch,
{
BusPendingActivation *pending_activation = data;
bus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
watch, babysitter_watch_callback, pending_activation);
_dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
watch, babysitter_watch_callback, pending_activation);
}
static dbus_bool_t
......@@ -806,11 +806,11 @@ bus_activation_activate_service (BusActivation *activation,
return FALSE;
}
if (!bus_loop_add_timeout (bus_context_get_loop (activation->context),
pending_activation->timeout,
handle_timeout_callback,
pending_activation,
NULL))
if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
pending_activation->timeout,
handle_timeout_callback,
pending_activation,
NULL))
{
BUS_SET_OOM (error);
bus_pending_activation_free (pending_activation);
......
......@@ -22,7 +22,6 @@
*/
#include "bus.h"
#include "loop.h"
#include "activation.h"
#include "connection.h"
#include "services.h"
......@@ -38,7 +37,7 @@ struct BusContext
int refcount;
char *type;
char *address;
BusLoop *loop;
DBusLoop *loop;
DBusList *servers;
BusConnections *connections;
BusActivation *activation;
......@@ -138,9 +137,9 @@ add_server_watch (DBusWatch *watch,
context = server_get_context (server);
return bus_loop_add_watch (context->loop,
watch, server_watch_callback, server,
NULL);
return _dbus_loop_add_watch (context->loop,
watch, server_watch_callback, server,
NULL);
}
static void
......@@ -152,8 +151,8 @@ remove_server_watch (DBusWatch *watch,
context = server_get_context (server);
bus_loop_remove_watch (context->loop,
watch, server_watch_callback, server);
_dbus_loop_remove_watch (context->loop,
watch, server_watch_callback, server);
}
......@@ -174,8 +173,8 @@ add_server_timeout (DBusTimeout *timeout,
context = server_get_context (server);
return bus_loop_add_timeout (context->loop,
timeout, server_timeout_callback, server, NULL);
return _dbus_loop_add_timeout (context->loop,
timeout, server_timeout_callback, server, NULL);
}
static void
......@@ -187,8 +186,8 @@ remove_server_timeout (DBusTimeout *timeout,
context = server_get_context (server);
bus_loop_remove_timeout (context->loop,
timeout, server_timeout_callback, server);
_dbus_loop_remove_timeout (context->loop,
timeout, server_timeout_callback, server);
}
static void
......@@ -396,7 +395,7 @@ bus_context_new (const DBusString *config_file,
*/
context->max_completed_connections = 1024;
context->loop = bus_loop_new ();
context->loop = _dbus_loop_new ();
if (context->loop == NULL)
{
BUS_SET_OOM (error);
......@@ -755,7 +754,7 @@ bus_context_unref (BusContext *context)
if (context->loop)
{
bus_loop_unref (context->loop);
_dbus_loop_unref (context->loop);
context->loop = NULL;
}
......@@ -798,7 +797,7 @@ bus_context_get_activation (BusContext *context)
return context->activation;
}
BusLoop*
DBusLoop*
bus_context_get_loop (BusContext *context)
{
return context->loop;
......
......@@ -28,8 +28,7 @@
#include <dbus/dbus.h>
#include <dbus/dbus-string.h>
#include "loop.h"
#include <dbus/dbus-mainloop.h>
typedef struct BusActivation BusActivation;
typedef struct BusConnections BusConnections;
......@@ -51,7 +50,7 @@ const char* bus_context_get_address (BusContext *context)
BusRegistry* bus_context_get_registry (BusContext *context);
BusConnections* bus_context_get_connections (BusContext *context);
BusActivation* bus_context_get_activation (BusContext *context);
BusLoop* bus_context_get_loop (BusContext *context);
DBusLoop* bus_context_get_loop (BusContext *context);
dbus_bool_t bus_context_allow_user (BusContext *context,
unsigned long uid);
BusPolicy* bus_context_create_connection_policy (BusContext *context,
......
......@@ -22,7 +22,6 @@
*/
#include "connection.h"
#include "dispatch.h"
#include "loop.h"
#include "policy.h"
#include "services.h"
#include "utils.h"
......@@ -89,7 +88,7 @@ connection_data_slot_unref (void)
}
}
static BusLoop*
static DBusLoop*
connection_get_loop (DBusConnection *connection)
{
BusConnectionData *d;
......@@ -134,7 +133,7 @@ bus_connection_disconnected (DBusConnection *connection)
while (transaction == NULL)
{
transaction = bus_transaction_new (d->connections->context);
bus_wait_for_memory ();
_dbus_wait_for_memory ();
}
if (!bus_service_remove_owner (service, connection,
......@@ -144,7 +143,7 @@ bus_connection_disconnected (DBusConnection *connection)
{
dbus_error_free (&error);
bus_transaction_cancel_and_free (transaction);
bus_wait_for_memory ();
_dbus_wait_for_memory ();
goto retry;
}
else
......@@ -209,9 +208,9 @@ add_connection_watch (DBusWatch *watch,
{
DBusConnection *connection = data;
return bus_loop_add_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection,
NULL);
return _dbus_loop_add_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection,
NULL);
}
static void
......@@ -220,8 +219,8 @@ remove_connection_watch (DBusWatch *watch,
{
DBusConnection *connection = data;
bus_loop_remove_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection);
_dbus_loop_remove_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection);
}
static void
......@@ -246,8 +245,8 @@ add_connection_timeout (DBusTimeout *timeout,
{
DBusConnection *connection = data;
return bus_loop_add_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection, NULL);
return _dbus_loop_add_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection, NULL);
}
static void
......@@ -256,8 +255,8 @@ remove_connection_timeout (DBusTimeout *timeout,
{
DBusConnection *connection = data;
bus_loop_remove_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection);
_dbus_loop_remove_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection);
}
static dbus_bool_t
......
......@@ -29,7 +29,6 @@
#include "utils.h"
#include "bus.h"
#include "test.h"
#include "loop.h"
#include <dbus/dbus-internals.h>
#include <string.h>
......@@ -176,7 +175,7 @@ bus_dispatch (DBusConnection *connection,
* until we can.
*/
while (!bus_connection_preallocate_oom_error (connection))
bus_wait_for_memory ();
_dbus_wait_for_memory ();
/* Ref connection in case we disconnect it at some point in here */
dbus_connection_ref (connection);
......@@ -537,7 +536,7 @@ kill_client_connection (BusContext *context,
_dbus_assert (s != NULL);
while ((base_service = _dbus_strdup (s)) == NULL)
bus_wait_for_memory ();
_dbus_wait_for_memory ();
dbus_connection_ref (connection);
......@@ -805,7 +804,7 @@ check_hello_message (BusContext *context,
{
_dbus_verbose ("no memory to get service name arg from hello\n");
dbus_error_free (&error);
bus_wait_for_memory ();
_dbus_wait_for_memory ();
goto retry_get_hello_name;
}
else
......@@ -819,7 +818,7 @@ check_hello_message (BusContext *context,
_dbus_verbose ("Got hello name: %s\n", name);
while (!dbus_bus_set_base_service (connection, name))
bus_wait_for_memory ();
_dbus_wait_for_memory ();
scd.skip_connection = NULL;
scd.failed = FALSE;
......@@ -849,7 +848,7 @@ check_hello_message (BusContext *context,
{
_dbus_verbose ("no memory to get service name arg from acquired\n");
dbus_error_free (&error);
bus_wait_for_memory ();
_dbus_wait_for_memory ();
goto retry_get_acquired_name;
}
else
......
/* -*- mode: C; c-file-style: "gnu" -*- */
/* loop.c Main loop for daemon
*
* Copyright (C) 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "loop.h"
#include "utils.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-sysdeps.h>
struct BusLoop
{
int refcount;
DBusList *callbacks;
int callback_list_serial;
int watch_count;
int timeout_count;
int depth; /**< number of recursive runs */
};
typedef enum
{
CALLBACK_WATCH,
CALLBACK_TIMEOUT
} CallbackType;
typedef struct
{
CallbackType type;
void *data;
DBusFreeFunction free_data_func;
} Callback;
typedef struct
{
Callback callback;
BusWatchFunction function;
DBusWatch *watch;
/* last watch handle failed due to OOM */
unsigned int last_iteration_oom : 1;
} WatchCallback;
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)
{
WatchCallback *cb;
cb = dbus_new (WatchCallback, 1);
if (cb == NULL)
return NULL;
cb->watch = watch;
cb->function = function;
cb->last_iteration_oom = FALSE;
cb->callback.type = CALLBACK_WATCH;
cb->callback.data = data;
cb->callback.free_data_func = free_data_func;
return 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 (BusLoop *loop,
Callback *cb)
{
if (!_dbus_list_append (&loop->callbacks, cb))
return FALSE;
loop->callback_list_serial += 1;
switch (cb->type)
{
case CALLBACK_WATCH:
loop->watch_count += 1;
break;
case CALLBACK_TIMEOUT:
loop->timeout_count += 1;
break;
}
return TRUE;
}
static void
remove_callback (BusLoop *loop,
DBusList *link)
{
Callback *cb = link->data;
switch (cb->type)
{
case CALLBACK_WATCH:
loop->watch_count -= 1;
break;
case CALLBACK_TIMEOUT:
loop->timeout_count -= 1;
break;
}
callback_free (cb);
_dbus_list_remove_link (&loop->callbacks, link);
loop->callback_list_serial += 1;
}
BusLoop*
bus_loop_new (void)
{
BusLoop *loop;
loop = dbus_new0 (BusLoop, 1);
if (loop == NULL)
return NULL;
loop->refcount = 1;
return loop;
}
void
bus_loop_ref (BusLoop *loop)
{
_dbus_assert (loop != NULL);
_dbus_assert (loop->refcount > 0);
loop->refcount += 1;
}
void
bus_loop_unref (BusLoop *loop)
{
_dbus_assert (loop != NULL);
_dbus_assert (loop->refcount > 0);
loop->refcount -= 1;
if (loop->refcount == 0)
{
dbus_free (loop);
}
}
dbus_bool_t
bus_loop_add_watch (BusLoop *loop,
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;
if (!add_callback (loop, (Callback*) wcb))
{
wcb->callback.free_data_func = NULL; /* don't want to have this side effect */
callback_free ((Callback*) wcb);
return FALSE;
}
return TRUE;
}
void
bus_loop_remove_watch (BusLoop *loop,
DBusWatch *watch,
BusWatchFunction function,
void *data)
{
DBusList *link;
link = _dbus_list_get_first_link (&loop->callbacks);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link);
Callback *this = link->data;
if (this->type == CALLBACK_WATCH &&
WATCH_CALLBACK (this)->watch == watch &&
this->data == data &&
WATCH_CALLBACK (this)->function == function)
{
remove_callback (loop, link);
return;
}
link = next;
}
_dbus_warn ("could not find watch %p function %p data %p to remove\n",
watch, function, data);
}
dbus_bool_t
bus_loop_add_timeout (BusLoop *loop,
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 (loop, (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 (BusLoop *loop,
DBusTimeout *timeout,
BusTimeoutFunction function,
void *data)
{
DBusList *link;
link = _dbus_list_get_first_link (&loop->callbacks);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&loop->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 (loop, link);
return;
}
link = next;
}
_dbus_warn ("could not find timeout %p function %p data %p to remove\n",
timeout, function, data);
}
/* Convolutions from GLib, there really must be a better way
* to do this.
*/
static dbus_bool_t
check_timeout (unsigned long tv_sec,
unsigned long tv_usec,
TimeoutCallback *tcb,
int *timeout)
{
long sec;
long msec;
unsigned long expiration_tv_sec;
unsigned long expiration_tv_usec;
long interval_seconds;
long interval_milliseconds;
int interval;
interval = dbus_timeout_get_interval (tcb->timeout);
interval_seconds = interval / 1000;
interval_milliseconds = interval - interval_seconds * 1000;
expiration_tv_sec = tcb->last_tv_sec + interval_seconds;
expiration_tv_usec = tcb->last_tv_usec + interval_milliseconds * 1000;
if (expiration_tv_usec >= 1000000)
{
expiration_tv_usec -= 1000000;
expiration_tv_sec += 1;
}
sec = expiration_tv_sec - tv_sec;
msec = (expiration_tv_usec - tv_usec) / 1000;
#if 0
printf ("Interval is %ld seconds %ld msecs\n",
interval_seconds,
interval_milliseconds);
printf ("Now is %lu seconds %lu usecs\n",
tv_sec, tv_usec);
printf ("Exp is %lu seconds %lu usecs\n",
expiration_tv_sec, expiration_tv_usec);
printf ("Pre-correction, remaining sec %ld msec %ld\n", sec, msec);
#endif
/* We do the following in a rather convoluted fashion to deal with
* the fact that we don't have an integral type big enough to hold
* the difference of two timevals in millseconds.
*/
if (sec < 0 || (sec == 0 && msec < 0))
msec = 0;
else
{
if (msec < 0)
{
msec += 1000;
sec -= 1;
}
if (sec > interval_seconds ||
(sec == interval_seconds && msec > interval_milliseconds))
{
/* The system time has been set backwards, reset the timeout */
tcb->last_tv_sec = tv_sec;
tcb->last_tv_usec = tv_usec;
msec = MIN (_DBUS_INT_MAX, interval);
_dbus_verbose ("System clock went backward\n");
}
else
{
msec = MIN (_DBUS_INT_MAX, (unsigned int)msec + 1000 * (unsigned int)sec);
}
}