Commit 6843ad31 authored by Havoc Pennington's avatar Havoc Pennington

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

	* dbus/dbus-dataslot.c (_dbus_data_slot_allocator_unref)
	(_dbus_data_slot_allocator_alloc): rework these to keep a
	reference count on each slot and automatically manage a global
	slot ID variable passed in by address

	* bus/bus.c: convert to new dataslot API

	* dbus/dbus-bus.c: convert to new dataslot API

	* dbus/dbus-connection.c: convert to new dataslot API

	* dbus/dbus-server.c: convert to new dataslot API

	* glib/dbus-gmain.c: ditto

	* bus/test.c: ditto

	* bus/connection.c: ditto
parent 8a71cf33
2003-06-22 Havoc Pennington <hp@pobox.com>
* dbus/dbus-dataslot.c (_dbus_data_slot_allocator_unref)
(_dbus_data_slot_allocator_alloc): rework these to keep a
reference count on each slot and automatically manage a global
slot ID variable passed in by address
* bus/bus.c: convert to new dataslot API
* dbus/dbus-bus.c: convert to new dataslot API
* dbus/dbus-connection.c: convert to new dataslot API
* dbus/dbus-server.c: convert to new dataslot API
* glib/dbus-gmain.c: ditto
* bus/test.c: ditto
* bus/connection.c: ditto
2003-06-22 Anders Carlsson <andersca@codefactory.se>
* configure.in: Add AM_PROG_GCJ and move AM_PROG_LIBTOOL
......
......@@ -48,8 +48,7 @@ struct BusContext
BusLimits limits;
};
static int server_data_slot = -1;
static int server_data_slot_refcount = 0;
static dbus_int32_t server_data_slot = -1;
typedef struct
{
......@@ -58,57 +57,25 @@ typedef struct
#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
static dbus_bool_t
server_data_slot_ref (void)
{
if (server_data_slot < 0)
{
server_data_slot = dbus_server_allocate_data_slot ();
if (server_data_slot < 0)
return FALSE;
_dbus_assert (server_data_slot_refcount == 0);
}
server_data_slot_refcount += 1;
return TRUE;
}
static void
server_data_slot_unref (void)
{
_dbus_assert (server_data_slot_refcount > 0);
server_data_slot_refcount -= 1;
if (server_data_slot_refcount == 0)
{
dbus_server_free_data_slot (server_data_slot);
server_data_slot = -1;
}
}
static BusContext*
server_get_context (DBusServer *server)
{
BusContext *context;
BusServerData *bd;
if (!server_data_slot_ref ())
if (!dbus_server_allocate_data_slot (&server_data_slot))
return NULL;
bd = BUS_SERVER_DATA (server);
if (bd == NULL)
{
server_data_slot_unref ();
dbus_server_free_data_slot (&server_data_slot);
return NULL;
}
context = bd->context;
server_data_slot_unref ();
dbus_server_free_data_slot (&server_data_slot);
return context;
}
......@@ -303,7 +270,7 @@ bus_context_new (const DBusString *config_file,
return NULL;
}
if (!server_data_slot_ref ())
if (!dbus_server_allocate_data_slot (&server_data_slot))
{
BUS_SET_OOM (error);
_dbus_string_free (&full_address);
......@@ -358,7 +325,7 @@ bus_context_new (const DBusString *config_file,
/* we need another ref of the server data slot for the context
* to own
*/
if (!server_data_slot_ref ())
if (!dbus_server_allocate_data_slot (&server_data_slot))
_dbus_assert_not_reached ("second ref of server data slot failed");
context->user_database = _dbus_user_database_new ();
......@@ -633,7 +600,7 @@ bus_context_new (const DBusString *config_file,
bus_config_parser_unref (parser);
_dbus_string_free (&full_address);
dbus_free_string_array (auth_mechanisms);
server_data_slot_unref ();
dbus_server_free_data_slot (&server_data_slot);
return context;
......@@ -647,7 +614,7 @@ bus_context_new (const DBusString *config_file,
_dbus_string_free (&full_address);
dbus_free_string_array (auth_mechanisms);
server_data_slot_unref ();
dbus_server_free_data_slot (&server_data_slot);
return NULL;
}
......@@ -769,7 +736,7 @@ bus_context_unref (BusContext *context)
dbus_free (context);
server_data_slot_unref ();
dbus_server_free_data_slot (&server_data_slot);
}
}
......
......@@ -43,8 +43,7 @@ struct BusConnections
DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */
};
static int connection_data_slot = -1;
static int connection_data_slot_refcount = 0;
static dbus_int32_t connection_data_slot = -1;
typedef struct
{
......@@ -67,39 +66,6 @@ static dbus_bool_t expire_incomplete_timeout (void *data);
#define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
static dbus_bool_t
connection_data_slot_ref (void)
{
if (connection_data_slot < 0)
{
connection_data_slot = dbus_connection_allocate_data_slot ();
if (connection_data_slot < 0)
return FALSE;
_dbus_assert (connection_data_slot_refcount == 0);
}
connection_data_slot_refcount += 1;
return TRUE;
}
static void
connection_data_slot_unref (void)
{
_dbus_assert (connection_data_slot_refcount > 0);
connection_data_slot_refcount -= 1;
if (connection_data_slot_refcount == 0)
{
dbus_connection_free_data_slot (connection_data_slot);
connection_data_slot = -1;
}
}
static DBusLoop*
connection_get_loop (DBusConnection *connection)
{
......@@ -419,7 +385,7 @@ bus_connections_new (BusContext *context)
{
BusConnections *connections;
if (!connection_data_slot_ref ())
if (!dbus_connection_allocate_data_slot (&connection_data_slot))
goto failed_0;
connections = dbus_new0 (BusConnections, 1);
......@@ -456,7 +422,7 @@ bus_connections_new (BusContext *context)
failed_2:
dbus_free (connections);
failed_1:
connection_data_slot_unref ();
dbus_connection_free_data_slot (&connection_data_slot);
failed_0:
return NULL;
}
......@@ -515,7 +481,7 @@ bus_connections_unref (BusConnections *connections)
dbus_free (connections);
connection_data_slot_unref ();
dbus_connection_free_data_slot (&connection_data_slot);
}
}
......
......@@ -32,8 +32,7 @@
#include <dbus/dbus-internals.h>
#include <string.h>
static int message_handler_slot = -1;
static int message_handler_slot_refcount;
static dbus_int32_t message_handler_slot = -1;
typedef struct
{
......@@ -309,48 +308,15 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
static dbus_bool_t
message_handler_slot_ref (void)
{
if (message_handler_slot < 0)
{
message_handler_slot = dbus_connection_allocate_data_slot ();
if (message_handler_slot < 0)
return FALSE;
_dbus_assert (message_handler_slot_refcount == 0);
}
message_handler_slot_refcount += 1;
return TRUE;
}
static void
message_handler_slot_unref (void)
{
_dbus_assert (message_handler_slot_refcount > 0);
message_handler_slot_refcount -= 1;
if (message_handler_slot_refcount == 0)
{
dbus_connection_free_data_slot (message_handler_slot);
message_handler_slot = -1;
}
}
static void
free_message_handler (void *data)
{
DBusMessageHandler *handler = data;
_dbus_assert (message_handler_slot >= 0);
_dbus_assert (message_handler_slot_refcount > 0);
dbus_message_handler_unref (handler);
message_handler_slot_unref ();
dbus_connection_free_data_slot (&message_handler_slot);
}
dbus_bool_t
......@@ -358,26 +324,25 @@ bus_dispatch_add_connection (DBusConnection *connection)
{
DBusMessageHandler *handler;
if (!message_handler_slot_ref ())
if (!dbus_connection_allocate_data_slot (&message_handler_slot))
return FALSE;
handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
if (handler == NULL)
{
message_handler_slot_unref ();
dbus_connection_free_data_slot (&message_handler_slot);
return FALSE;
}
if (!dbus_connection_add_filter (connection, handler))
{
dbus_message_handler_unref (handler);
message_handler_slot_unref ();
dbus_connection_free_data_slot (&message_handler_slot);
return FALSE;
}
_dbus_assert (message_handler_slot >= 0);
_dbus_assert (message_handler_slot_refcount > 0);
if (!dbus_connection_set_data (connection,
message_handler_slot,
......@@ -385,7 +350,7 @@ bus_dispatch_add_connection (DBusConnection *connection)
free_message_handler))
{
dbus_message_handler_unref (handler);
message_handler_slot_unref ();
dbus_connection_free_data_slot (&message_handler_slot);
return FALSE;
}
......
......@@ -123,41 +123,7 @@ client_disconnect_handler (DBusMessageHandler *handler,
return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
static int handler_slot = -1;
static int handler_slot_refcount = 0;
static dbus_bool_t
handler_slot_ref (void)
{
if (handler_slot < 0)
{
handler_slot = dbus_connection_allocate_data_slot ();
if (handler_slot < 0)
return FALSE;
_dbus_assert (handler_slot_refcount == 0);
}
handler_slot_refcount += 1;
return TRUE;
}
static void
handler_slot_unref (void)
{
_dbus_assert (handler_slot_refcount > 0);
handler_slot_refcount -= 1;
if (handler_slot_refcount == 0)
{
dbus_connection_free_data_slot (handler_slot);
handler_slot = -1;
}
}
static dbus_int32_t handler_slot = -1;
static void
free_handler (void *data)
......@@ -165,7 +131,7 @@ free_handler (void *data)
DBusMessageHandler *handler = data;
dbus_message_handler_unref (handler);
handler_slot_unref ();
dbus_connection_free_data_slot (&handler_slot);
}
dbus_bool_t
......@@ -217,7 +183,7 @@ bus_setup_debug_client (DBusConnection *connection)
if (!_dbus_list_append (&clients, connection))
goto out;
if (!handler_slot_ref ())
if (!dbus_connection_allocate_data_slot (&handler_slot))
goto out;
/* Set up handler to be destroyed */
......@@ -225,7 +191,7 @@ bus_setup_debug_client (DBusConnection *connection)
disconnect_handler,
free_handler))
{
handler_slot_unref ();
dbus_connection_free_data_slot (&handler_slot);
goto out;
}
......
......@@ -56,12 +56,9 @@ typedef struct
unsigned int is_well_known : 1; /**< Is one of the well-known connections in our global array */
} BusData;
/** The slot we have reserved to store BusData
/** The slot we have reserved to store BusData.
*/
static int bus_data_slot = -1;
/** Number of connections using the slot
*/
static int bus_data_slot_refcount = 0;
static dbus_int32_t bus_data_slot = -1;
/** Number of bus types */
#define N_BUS_TYPES 3
......@@ -194,50 +191,6 @@ init_connections_unlocked (void)
return initialized;
}
static dbus_bool_t
data_slot_ref (void)
{
_DBUS_LOCK (bus);
if (bus_data_slot < 0)
{
bus_data_slot = dbus_connection_allocate_data_slot ();
if (bus_data_slot < 0)
{
_DBUS_UNLOCK (bus);
return FALSE;
}
_dbus_assert (bus_data_slot_refcount == 0);
}
bus_data_slot_refcount += 1;
_DBUS_UNLOCK (bus);
return TRUE;
}
static void
data_slot_unref (void)
{
_DBUS_LOCK (bus);
_dbus_assert (bus_data_slot_refcount > 0);
_dbus_assert (bus_data_slot >= 0);
bus_data_slot_refcount -= 1;
if (bus_data_slot_refcount == 0)
{
dbus_connection_free_data_slot (bus_data_slot);
bus_data_slot = -1;
}
_DBUS_UNLOCK (bus);
}
static void
bus_data_free (void *data)
{
......@@ -262,7 +215,7 @@ bus_data_free (void *data)
dbus_free (bd->base_service);
dbus_free (bd);
data_slot_unref ();
dbus_connection_free_data_slot (&bus_data_slot);
}
static BusData*
......@@ -270,7 +223,7 @@ ensure_bus_data (DBusConnection *connection)
{
BusData *bd;
if (!data_slot_ref ())
if (!dbus_connection_allocate_data_slot (&bus_data_slot))
return NULL;
bd = dbus_connection_get_data (connection, bus_data_slot);
......@@ -279,7 +232,7 @@ ensure_bus_data (DBusConnection *connection)
bd = dbus_new0 (BusData, 1);
if (bd == NULL)
{
data_slot_unref ();
dbus_connection_free_data_slot (&bus_data_slot);
return NULL;
}
......@@ -289,7 +242,7 @@ ensure_bus_data (DBusConnection *connection)
bus_data_free))
{
dbus_free (bd);
data_slot_unref ();
dbus_connection_free_data_slot (&bus_data_slot);
return NULL;
}
......@@ -297,7 +250,7 @@ ensure_bus_data (DBusConnection *connection)
}
else
{
data_slot_unref ();
dbus_connection_free_data_slot (&bus_data_slot);
}
return bd;
......
......@@ -2933,34 +2933,41 @@ _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
* Allocates an integer ID to be used for storing application-specific
* data on any DBusConnection. The allocated ID may then be used
* with dbus_connection_set_data() and dbus_connection_get_data().
* If allocation fails, -1 is returned. Again, the allocated
* slot is global, i.e. all DBusConnection objects will
* The passed-in slot must be initialized to -1, and is filled in
* with the slot ID. If the passed-in slot is not -1, it's assumed
* to be already allocated, and its refcount is incremented.
*
* The allocated slot is global, i.e. all DBusConnection objects will
* have a slot with the given integer ID reserved.
*
* @returns -1 on failure, otherwise the data slot ID
* @param slot_p address of a global variable storing the slot
* @returns #FALSE on failure (no memory)
*/
int
dbus_connection_allocate_data_slot (void)
dbus_bool_t
dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
{
return _dbus_data_slot_allocator_alloc (&slot_allocator,
_DBUS_LOCK_NAME (connection_slots));
_DBUS_LOCK_NAME (connection_slots),
slot_p);
}
/**
* Deallocates a global ID for connection data slots.
* dbus_connection_get_data() and dbus_connection_set_data()
* may no longer be used with this slot.
* Existing data stored on existing DBusConnection objects
* will be freed when the connection is finalized,
* but may not be retrieved (and may only be replaced
* if someone else reallocates the slot).
* dbus_connection_get_data() and dbus_connection_set_data() may no
* longer be used with this slot. Existing data stored on existing
* DBusConnection objects will be freed when the connection is
* finalized, but may not be retrieved (and may only be replaced if
* someone else reallocates the slot). When the refcount on the
* passed-in slot reaches 0, it is set to -1.
*
* @param slot the slot to deallocate
* @param slot_p address storing the slot to deallocate
*/
void
dbus_connection_free_data_slot (int slot)
dbus_connection_free_data_slot (dbus_int32_t *slot_p)
{
_dbus_data_slot_allocator_free (&slot_allocator, slot);
_dbus_return_if_fail (*slot_p >= 0);
_dbus_data_slot_allocator_free (&slot_allocator, slot_p);
}
/**
......@@ -2978,7 +2985,7 @@ dbus_connection_free_data_slot (int slot)
*/
dbus_bool_t
dbus_connection_set_data (DBusConnection *connection,
int slot,
dbus_int32_t slot,
void *data,
DBusFreeFunction free_data_func)
{
......@@ -3018,7 +3025,7 @@ dbus_connection_set_data (DBusConnection *connection,
*/
void*
dbus_connection_get_data (DBusConnection *connection,
int slot)
dbus_int32_t slot)
{
void *res;
......
......@@ -172,14 +172,14 @@ void dbus_connection_unregister_handler (DBusConnection *connection,
int n_messages);
int dbus_connection_allocate_data_slot (void);
void dbus_connection_free_data_slot (int slot);
dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p);
void dbus_connection_free_data_slot (dbus_int32_t *slot_p);
dbus_bool_t dbus_connection_set_data (DBusConnection *connection,
int slot,
dbus_int32_t slot,
void *data,
DBusFreeFunction free_data_func);
void* dbus_connection_get_data (DBusConnection *connection,
int slot);
dbus_int32_t slot);
void dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe);
......
......@@ -53,24 +53,25 @@ _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator)
/**
* Allocates an integer ID to be used for storing data
* in a #DBusDataSlotList.
*
* @todo all over the code we have foo_slot and foo_slot_refcount,
* would be better to add an interface for that to
* DBusDataSlotAllocator so it isn't cut-and-pasted everywhere.
* in a #DBusDataSlotList. If the value at *slot_id_p is
* not -1, this function just increments the refcount for
* the existing slot ID. If the value is -1, a new slot ID
* is allocated and stored at *slot_id_p.
*
* @param allocator the allocator
* @param mutex the lock for this allocator
* @returns the integer ID, or -1 on failure
* @param slot_id_p address to fill with the slot ID
* @returns #TRUE on success
*/
int
dbus_bool_t
_dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
DBusMutex *mutex)
DBusMutex *mutex,
dbus_int32_t *slot_id_p)
{
int slot;
dbus_int32_t slot;
if (!dbus_mutex_lock (mutex))
return -1;
return FALSE;
if (allocator->n_allocated_slots == 0)
{
......@@ -79,15 +80,30 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
}
else
_dbus_assert (allocator->lock == mutex);
if (*slot_id_p >= 0)
{
slot = *slot_id_p;
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
allocator->allocated_slots[slot].refcount += 1;
goto out;
}
_dbus_assert (*slot_id_p < 0);
if (allocator->n_used_slots < allocator->n_allocated_slots)
{
slot = 0;
while (slot < allocator->n_allocated_slots)
{
if (allocator->allocated_slots[slot] < 0)
if (allocator->allocated_slots[slot].slot_id < 0)
{
allocator->allocated_slots[slot] = slot;
allocator->allocated_slots[slot].slot_id = slot;
allocator->allocated_slots[slot].refcount = 1;
allocator->n_used_slots += 1;
break;
}
......@@ -98,11 +114,11 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
}
else
{
int *tmp;
DBusAllocatedSlot *tmp;
slot = -1;
tmp = dbus_realloc (allocator->allocated_slots,
sizeof (int) * (allocator->n_allocated_slots + 1));
sizeof (DBusAllocatedSlot) * (allocator->n_allocated_slots + 1));
if (tmp == NULL)
goto out;
......@@ -110,18 +126,24 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
slot = allocator->n_allocated_slots;
allocator->n_allocated_slots += 1;
allocator->n_used_slots += 1;
allocator->allocated_slots[slot] = slot;
allocator->allocated_slots[slot].slot_id = slot;
allocator->allocated_slots[slot].refcount = 1;
}
_dbus_assert (slot >= 0);
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (*slot_id_p < 0);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
_dbus_assert (allocator->allocated_slots[slot].refcount == 1);
*slot_id_p = slot;
_dbus_verbose ("Allocated slot %d on allocator %p total %d slots allocated %d used\n",
slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots);
out:
dbus_mutex_unlock (allocator->lock);
return slot;
return slot >= 0;
}
/**
......@@ -130,24 +152,37 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
* existing #DBusDataList objects with this ID will be freed when the
* data list is finalized, but may not be retrieved (and may only be
* replaced if someone else reallocates the slot).
* The slot value is reset to -1 if this is the last unref.
*
* @param allocator the allocator
* @param slot the slot to deallocate
* @param slot_id_p address where we store the slot
*/
void
_dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
int slot)
dbus_int32_t *slot_id_p)
{
dbus_mutex_lock (allocator->lock);
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot] == slot);
_dbus_assert (*slot_id_p < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[*slot_id_p].slot_id == *slot_id_p);
_dbus_assert (allocator->allocated_slots[*slot_id_p].refcount > 0);
allocator->allocated_slots[*slot_id_p].refcount -= 1;
if (allocator->allocated_slots[*slot_id_p].refcount > 0)
{
dbus_mutex_unlock (allocator->lock);
return;
}
/* refcount is 0, free the slot */
_dbus_verbose ("Freeing slot %d on allocator %p total %d allocated %d used\n",
*slot_id_p, allocator, allocator->n_allocated_slots, allocator->n_used_slots);
allocator->allocated_slots[*slot_id_p].slot_id = -1;
*slot_id_p = -1;
allocator->allocated_slots[slot] = -1;
allocator->n_used_slots -= 1;
_dbus_verbose ("Freed slot %d on allocator %p total %d allocated %d used\n",
slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots);
if (allocator->n_used_slots == 0)
{
......@@ -211,7 +246,7 @@ _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator,
if (!dbus_mutex_lock (allocator->lock))
return FALSE;
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot] == slot);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
dbus_mutex_unlock (allocator->lock);
#endif
......@@ -270,7 +305,7 @@ _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator,
return FALSE;
_dbus_assert