mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-04 08:18:00 +02:00
2003-01-05 Havoc Pennington <hp@pobox.com>
* bus/connection.c: implement routines for handling connections, first thing is keeping a list of owned services on each connection and setting up watches etc. * bus/services.c: implement a mapping from service names to lists of connections * dbus/dbus-hash.c: add DBUS_HASH_POINTER * dbus/dbus-threads.c (dbus_static_mutex_lock): add functions to use static mutexes for global data * dbus/dbus-connection.c (dbus_connection_set_data): add new collection of functions to set/get application-specific data on the DBusConnection.
This commit is contained in:
parent
c92339de11
commit
96a9f80300
14 changed files with 904 additions and 108 deletions
18
ChangeLog
18
ChangeLog
|
|
@ -1,3 +1,21 @@
|
|||
2003-01-05 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* bus/connection.c: implement routines for handling connections,
|
||||
first thing is keeping a list of owned services on each connection
|
||||
and setting up watches etc.
|
||||
|
||||
* bus/services.c: implement a mapping from service names to lists
|
||||
of connections
|
||||
|
||||
* dbus/dbus-hash.c: add DBUS_HASH_POINTER
|
||||
|
||||
* dbus/dbus-threads.c (dbus_static_mutex_lock): add functions
|
||||
to use static mutexes for global data
|
||||
|
||||
* dbus/dbus-connection.c (dbus_connection_set_data): add new
|
||||
collection of functions to set/get application-specific data
|
||||
on the DBusConnection.
|
||||
|
||||
2003-01-04 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* dbus/dbus-sysdeps.c (_dbus_sleep_milliseconds): new function
|
||||
|
|
|
|||
|
|
@ -7,9 +7,13 @@ EFENCE=
|
|||
bin_PROGRAMS=dbus-daemon-1
|
||||
|
||||
dbus_daemon_1_SOURCES= \
|
||||
connection.c \
|
||||
connection.h \
|
||||
loop.c \
|
||||
loop.h \
|
||||
main.c
|
||||
main.c \
|
||||
services.c \
|
||||
services.h
|
||||
|
||||
dbus_daemon_1_LDADD= \
|
||||
$(EFENCE) \
|
||||
|
|
|
|||
186
bus/connection.c
Normal file
186
bus/connection.c
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* connection.c Client connections
|
||||
*
|
||||
* 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 "connection.h"
|
||||
#include "loop.h"
|
||||
#include "services.h"
|
||||
#include <dbus/dbus-list.h>
|
||||
|
||||
static int connection_data_slot;
|
||||
static DBusList *connections = NULL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DBusList *services_owned;
|
||||
|
||||
} BusConnectionData;
|
||||
|
||||
#define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
|
||||
|
||||
static void
|
||||
connection_error_handler (DBusConnection *connection,
|
||||
DBusResultCode error_code,
|
||||
void *data)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
BusService *service;
|
||||
|
||||
_dbus_warn ("Error on connection: %s\n",
|
||||
dbus_result_to_string (error_code));
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
/* we don't want to be called again since we're dropping the connection */
|
||||
dbus_connection_set_error_function (connection, NULL, NULL, NULL);
|
||||
|
||||
/* Drop any service ownership */
|
||||
while ((service = _dbus_list_get_last (&d->services_owned)))
|
||||
bus_service_remove_owner (service, connection);
|
||||
|
||||
/* no more watching */
|
||||
dbus_connection_set_watch_functions (connection,
|
||||
NULL, NULL,
|
||||
connection,
|
||||
NULL);
|
||||
|
||||
dbus_connection_set_data (connection,
|
||||
connection_data_slot,
|
||||
NULL, NULL);
|
||||
|
||||
_dbus_list_remove (&connections, connection);
|
||||
dbus_connection_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_watch_callback (DBusWatch *watch,
|
||||
unsigned int condition,
|
||||
void *data)
|
||||
{
|
||||
DBusConnection *connection = data;
|
||||
|
||||
dbus_connection_handle_watch (connection, watch, condition);
|
||||
}
|
||||
|
||||
static void
|
||||
add_connection_watch (DBusWatch *watch,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
bus_loop_add_watch (watch, connection_watch_callback, connection,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_connection_watch (DBusWatch *watch,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
bus_loop_remove_watch (watch, connection_watch_callback, connection);
|
||||
}
|
||||
|
||||
static void
|
||||
free_connection_data (void *data)
|
||||
{
|
||||
BusConnectionData *d = data;
|
||||
|
||||
/* services_owned should be NULL since we should be disconnected */
|
||||
_dbus_assert (d->services_owned == NULL);
|
||||
|
||||
dbus_free (d);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_init (void)
|
||||
{
|
||||
connection_data_slot = dbus_connection_allocate_data_slot ();
|
||||
|
||||
if (connection_data_slot < 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_setup (DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = dbus_new (BusConnectionData, 1);
|
||||
if (d == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!dbus_connection_set_data (connection,
|
||||
connection_data_slot,
|
||||
d, free_connection_data))
|
||||
{
|
||||
dbus_free (d);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_list_append (&connections, connection))
|
||||
{
|
||||
/* this will free our data when connection gets finalized */
|
||||
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);
|
||||
|
||||
dbus_connection_set_error_function (connection,
|
||||
connection_error_handler,
|
||||
NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_add_owned_service (DBusConnection *connection,
|
||||
BusService *service)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
if (!_dbus_list_append (&d->services_owned,
|
||||
service))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
bus_connection_remove_owned_service (DBusConnection *connection,
|
||||
BusService *service)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
_dbus_list_remove_last (&d->services_owned, service);
|
||||
}
|
||||
41
bus/connection.h
Normal file
41
bus/connection.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* connection.h Client connections
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BUS_CONNECTION_H
|
||||
#define BUS_CONNECTION_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include "services.h"
|
||||
|
||||
dbus_bool_t bus_connection_init (void);
|
||||
|
||||
dbus_bool_t bus_connection_setup (DBusConnection *connection);
|
||||
|
||||
|
||||
/* called by services.c */
|
||||
dbus_bool_t bus_connection_add_owned_service (DBusConnection *connection,
|
||||
BusService *service);
|
||||
void bus_connection_remove_owned_service (DBusConnection *connection,
|
||||
BusService *service);
|
||||
|
||||
#endif /* BUS_CONNECTION_H */
|
||||
|
|
@ -173,7 +173,11 @@ bus_loop_run (void)
|
|||
initial_serial = watch_list_serial;
|
||||
i = 0;
|
||||
while (i < n_fds)
|
||||
{
|
||||
{
|
||||
/* FIXME I think this "restart if we change the watches"
|
||||
* approach could result in starving watches
|
||||
* toward the end of the list.
|
||||
*/
|
||||
if (initial_serial != watch_list_serial)
|
||||
goto next_iteration;
|
||||
|
||||
|
|
|
|||
72
bus/main.c
72
bus/main.c
|
|
@ -21,35 +21,8 @@
|
|||
*
|
||||
*/
|
||||
#include "loop.h"
|
||||
#include "connection.h"
|
||||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
static DBusList *connections = NULL;
|
||||
|
||||
static void
|
||||
connection_error_handler (DBusConnection *connection,
|
||||
DBusResultCode error_code,
|
||||
void *data)
|
||||
{
|
||||
_dbus_warn ("Error on connection: %s\n",
|
||||
dbus_result_to_string (error_code));
|
||||
|
||||
/* we don't want to be called again since we're dropping the connection */
|
||||
dbus_connection_set_error_function (connection, NULL, NULL, NULL);
|
||||
|
||||
_dbus_list_remove (&connections, connection);
|
||||
dbus_connection_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_watch_callback (DBusWatch *watch,
|
||||
unsigned int condition,
|
||||
void *data)
|
||||
{
|
||||
DBusConnection *connection = data;
|
||||
|
||||
dbus_connection_handle_watch (connection, watch, condition);
|
||||
}
|
||||
|
||||
static void
|
||||
server_watch_callback (DBusWatch *watch,
|
||||
|
|
@ -61,21 +34,6 @@ server_watch_callback (DBusWatch *watch,
|
|||
dbus_server_handle_watch (server, watch, condition);
|
||||
}
|
||||
|
||||
static void
|
||||
add_connection_watch (DBusWatch *watch,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
bus_loop_add_watch (watch, connection_watch_callback, connection,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_connection_watch (DBusWatch *watch,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
bus_loop_remove_watch (watch, connection_watch_callback, connection);
|
||||
}
|
||||
|
||||
static void
|
||||
add_server_watch (DBusWatch *watch,
|
||||
DBusServer *server)
|
||||
|
|
@ -91,30 +49,6 @@ remove_server_watch (DBusWatch *watch,
|
|||
bus_loop_remove_watch (watch, server_watch_callback, server);
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
setup_connection (DBusConnection *connection)
|
||||
{
|
||||
if (!_dbus_list_append (&connections, connection))
|
||||
{
|
||||
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);
|
||||
|
||||
dbus_connection_set_error_function (connection,
|
||||
connection_error_handler,
|
||||
NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_server (DBusServer *server)
|
||||
{
|
||||
|
|
@ -130,7 +64,7 @@ new_connection_callback (DBusServer *server,
|
|||
DBusConnection *new_connection,
|
||||
void *data)
|
||||
{
|
||||
if (!setup_connection (new_connection))
|
||||
if (!bus_connection_setup (new_connection))
|
||||
; /* we won't have ref'd the connection so it will die */
|
||||
}
|
||||
|
||||
|
|
@ -156,6 +90,8 @@ main (int argc, char **argv)
|
|||
|
||||
setup_server (server);
|
||||
|
||||
bus_connection_init ();
|
||||
|
||||
dbus_server_set_new_connection_function (server,
|
||||
new_connection_callback,
|
||||
NULL, NULL);
|
||||
|
|
|
|||
154
bus/services.c
Normal file
154
bus/services.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* services.c Service management
|
||||
*
|
||||
* 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 "services.h"
|
||||
#include "connection.h"
|
||||
#include <dbus/dbus-hash.h>
|
||||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-mempool.h>
|
||||
|
||||
struct BusService
|
||||
{
|
||||
char *name;
|
||||
DBusList *owners;
|
||||
};
|
||||
|
||||
static DBusHashTable *service_hash = NULL;
|
||||
static DBusMemPool *service_pool = NULL;
|
||||
|
||||
BusService*
|
||||
bus_service_lookup (const DBusString *service_name,
|
||||
dbus_bool_t create_if_not_found)
|
||||
{
|
||||
const char *c_name;
|
||||
BusService *service;
|
||||
|
||||
if (service_hash == NULL)
|
||||
{
|
||||
service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
NULL, NULL);
|
||||
service_pool = _dbus_mem_pool_new (sizeof (BusService),
|
||||
TRUE);
|
||||
|
||||
if (service_hash == NULL || service_pool == NULL)
|
||||
{
|
||||
if (service_hash)
|
||||
{
|
||||
_dbus_hash_table_unref (service_hash);
|
||||
service_hash = NULL;
|
||||
}
|
||||
if (service_pool)
|
||||
{
|
||||
_dbus_mem_pool_free (service_pool);
|
||||
service_pool = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_dbus_string_get_const_data (service_name, &c_name);
|
||||
|
||||
service = _dbus_hash_table_lookup_string (service_hash,
|
||||
c_name);
|
||||
if (service != NULL)
|
||||
return service;
|
||||
|
||||
if (!create_if_not_found)
|
||||
return NULL;
|
||||
|
||||
service = _dbus_mem_pool_alloc (service_pool);
|
||||
if (service == NULL)
|
||||
return NULL;
|
||||
|
||||
service->name = _dbus_strdup (c_name);
|
||||
if (service->name == NULL)
|
||||
{
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dbus_hash_table_insert_string (service_hash,
|
||||
service->name,
|
||||
service))
|
||||
{
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_service_add_owner (BusService *service,
|
||||
DBusConnection *owner)
|
||||
{
|
||||
if (!_dbus_list_append (&service->owners,
|
||||
owner))
|
||||
return FALSE;
|
||||
|
||||
if (!bus_connection_add_owned_service (owner, service))
|
||||
{
|
||||
_dbus_list_remove_last (&service->owners, owner);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
bus_service_remove_owner (BusService *service,
|
||||
DBusConnection *owner)
|
||||
{
|
||||
_dbus_list_remove_last (&service->owners, owner);
|
||||
bus_connection_remove_owned_service (owner, service);
|
||||
}
|
||||
|
||||
DBusConnection*
|
||||
bus_service_get_primary_owner (BusService *service)
|
||||
{
|
||||
return _dbus_list_get_first (&service->owners);
|
||||
}
|
||||
|
||||
const char*
|
||||
bus_service_get_name (BusService *service)
|
||||
{
|
||||
return service->name;
|
||||
}
|
||||
|
||||
void
|
||||
bus_service_foreach (BusServiceForeachFunction function,
|
||||
void *data)
|
||||
{
|
||||
DBusHashIter iter;
|
||||
|
||||
if (service_hash == NULL)
|
||||
return;
|
||||
|
||||
_dbus_hash_iter_init (service_hash, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
BusService *service = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
(* function) (service, data);
|
||||
}
|
||||
}
|
||||
53
bus/services.h
Normal file
53
bus/services.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* services.h Service management
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BUS_SERVICES_H
|
||||
#define BUS_SERVICES_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-string.h>
|
||||
|
||||
/* Each service can have multiple owners; one owner is the "real
|
||||
* owner" and the others are queued up. For example, if I have
|
||||
* multiple text editors open, one might own the TextEditor service;
|
||||
* if I close that one, the next in line will become the owner of it.
|
||||
*/
|
||||
|
||||
typedef struct BusService BusService;
|
||||
|
||||
typedef void (* BusServiceForeachFunction) (BusService *service,
|
||||
void *data);
|
||||
|
||||
BusService* bus_service_lookup (const DBusString *service_name,
|
||||
dbus_bool_t create_if_not_found);
|
||||
dbus_bool_t bus_service_add_owner (BusService *service,
|
||||
DBusConnection *owner);
|
||||
void bus_service_remove_owner (BusService *service,
|
||||
DBusConnection *owner);
|
||||
DBusConnection* bus_service_get_primary_owner (BusService *service);
|
||||
const char* bus_service_get_name (BusService *service);
|
||||
|
||||
void bus_service_foreach (BusServiceForeachFunction function,
|
||||
void *data);
|
||||
|
||||
#endif /* BUS_SERVICES_H */
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbus-list.h"
|
||||
#include "dbus-hash.h"
|
||||
#include "dbus-message-internal.h"
|
||||
#include "dbus-threads.h"
|
||||
|
||||
/**
|
||||
* @defgroup DBusConnection DBusConnection
|
||||
|
|
@ -57,6 +58,15 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/** Opaque typedef for DBusDataSlot */
|
||||
typedef struct DBusDataSlot DBusDataSlot;
|
||||
/** DBusDataSlot is used to store application data on the connection */
|
||||
struct DBusDataSlot
|
||||
{
|
||||
void *data; /**< The application data */
|
||||
DBusFreeFunction free_data_func; /**< Free the application data */
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation details of DBusConnection. All fields are private.
|
||||
*/
|
||||
|
|
@ -80,8 +90,12 @@ struct DBusConnection
|
|||
DBusList *filter_list; /**< List of filters. */
|
||||
int filters_serial; /**< Increments when the list of filters is changed. */
|
||||
int handlers_serial; /**< Increments when the handler table is changed. */
|
||||
DBusDataSlot *data_slots; /**< Data slots */
|
||||
int n_slots; /**< Slots allocated so far. */
|
||||
};
|
||||
|
||||
static void _dbus_connection_free_data_slots (DBusConnection *connection);
|
||||
|
||||
/**
|
||||
* Adds a message to the incoming message queue, returning #FALSE
|
||||
* if there's insufficient memory to queue the message.
|
||||
|
|
@ -313,6 +327,9 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
|
|||
connection->watches = watch_list;
|
||||
connection->handler_table = handler_table;
|
||||
connection->filter_list = NULL;
|
||||
|
||||
connection->data_slots = NULL;
|
||||
connection->n_slots = 0;
|
||||
|
||||
_dbus_transport_ref (transport);
|
||||
_dbus_transport_set_connection (transport, connection);
|
||||
|
|
@ -449,13 +466,15 @@ dbus_connection_unref (DBusConnection *connection)
|
|||
{
|
||||
DBusHashIter iter;
|
||||
DBusList *link;
|
||||
|
||||
|
||||
/* free error data as a side effect */
|
||||
dbus_connection_set_error_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
_dbus_watch_list_free (connection->watches);
|
||||
connection->watches = NULL;
|
||||
|
||||
_dbus_connection_free_data_slots (connection);
|
||||
|
||||
_dbus_hash_iter_init (connection->handler_table, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
|
|
@ -1059,4 +1078,193 @@ dbus_connection_unregister_handler (DBusConnection *connection,
|
|||
connection->handlers_serial += 1;
|
||||
}
|
||||
|
||||
static int *allocated_slots = NULL;
|
||||
static int n_allocated_slots = 0;
|
||||
static int n_used_slots = 0;
|
||||
static DBusStaticMutex allocated_slots_lock = DBUS_STATIC_MUTEX_INIT;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @returns -1 on failure, otherwise the data slot ID
|
||||
*/
|
||||
int
|
||||
dbus_connection_allocate_data_slot (void)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if (!dbus_static_mutex_lock (&allocated_slots_lock))
|
||||
return -1;
|
||||
|
||||
if (n_used_slots < n_allocated_slots)
|
||||
{
|
||||
slot = 0;
|
||||
while (slot < n_allocated_slots)
|
||||
{
|
||||
if (allocated_slots[slot] < 0)
|
||||
{
|
||||
allocated_slots[slot] = slot;
|
||||
n_used_slots += 1;
|
||||
break;
|
||||
}
|
||||
++slot;
|
||||
}
|
||||
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
}
|
||||
else
|
||||
{
|
||||
int *tmp;
|
||||
|
||||
slot = -1;
|
||||
tmp = dbus_realloc (allocated_slots,
|
||||
sizeof (int) * (n_allocated_slots + 1));
|
||||
if (tmp == NULL)
|
||||
goto out;
|
||||
|
||||
allocated_slots = tmp;
|
||||
slot = n_allocated_slots;
|
||||
n_allocated_slots += 1;
|
||||
n_used_slots += 1;
|
||||
allocated_slots[slot] = slot;
|
||||
}
|
||||
|
||||
_dbus_assert (slot >= 0);
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
|
||||
out:
|
||||
dbus_static_mutex_unlock (&allocated_slots_lock);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param slot the slot to deallocate
|
||||
*/
|
||||
void
|
||||
dbus_connection_free_data_slot (int slot)
|
||||
{
|
||||
dbus_static_mutex_lock (&allocated_slots_lock);
|
||||
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
_dbus_assert (allocated_slots[slot] == slot);
|
||||
|
||||
allocated_slots[slot] = -1;
|
||||
n_used_slots -= 1;
|
||||
|
||||
if (n_used_slots == 0)
|
||||
{
|
||||
dbus_free (allocated_slots);
|
||||
allocated_slots = NULL;
|
||||
n_allocated_slots = 0;
|
||||
}
|
||||
|
||||
dbus_static_mutex_unlock (&allocated_slots_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a pointer on a DBusConnection, along
|
||||
* with an optional function to be used for freeing
|
||||
* the data when the data is set again, or when
|
||||
* the connection is finalized. The slot number
|
||||
* must have been allocated with dbus_connection_allocate_data_slot().
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param slot the slot number
|
||||
* @param data the data to store
|
||||
* @param free_data_func finalizer function for the data
|
||||
* @returns #TRUE if there was enough memory to store the data
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_connection_set_data (DBusConnection *connection,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func)
|
||||
{
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
_dbus_assert (allocated_slots[slot] == slot);
|
||||
|
||||
if (slot >= connection->n_slots)
|
||||
{
|
||||
DBusDataSlot *tmp;
|
||||
int i;
|
||||
|
||||
tmp = dbus_realloc (connection->data_slots,
|
||||
sizeof (DBusDataSlot) * (slot + 1));
|
||||
if (tmp == NULL)
|
||||
return FALSE;
|
||||
|
||||
connection->data_slots = tmp;
|
||||
i = connection->n_slots;
|
||||
connection->n_slots = slot + 1;
|
||||
while (i < connection->n_slots)
|
||||
{
|
||||
connection->data_slots[i].data = NULL;
|
||||
connection->data_slots[i].free_data_func = NULL;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
_dbus_assert (slot < connection->n_slots);
|
||||
|
||||
if (connection->data_slots[slot].free_data_func)
|
||||
(* connection->data_slots[slot].free_data_func) (connection->data_slots[slot].data);
|
||||
|
||||
connection->data_slots[slot].data = data;
|
||||
connection->data_slots[slot].free_data_func = free_data_func;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data previously set with dbus_connection_set_data().
|
||||
* The slot must still be allocated (must not have been freed).
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param slot the slot to get data from
|
||||
* @returns the data, or #NULL if not found
|
||||
*/
|
||||
void*
|
||||
dbus_connection_get_data (DBusConnection *connection,
|
||||
int slot)
|
||||
{
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
_dbus_assert (allocated_slots[slot] == slot);
|
||||
|
||||
if (slot >= connection->n_slots)
|
||||
return NULL;
|
||||
|
||||
return connection->data_slots[slot].data;
|
||||
}
|
||||
|
||||
static void
|
||||
_dbus_connection_free_data_slots (DBusConnection *connection)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < connection->n_slots)
|
||||
{
|
||||
if (connection->data_slots[i].free_data_func)
|
||||
(* connection->data_slots[i].free_data_func) (connection->data_slots[i].data);
|
||||
connection->data_slots[i].data = NULL;
|
||||
connection->data_slots[i].free_data_func = NULL;
|
||||
++i;
|
||||
}
|
||||
|
||||
dbus_free (connection->data_slots);
|
||||
connection->data_slots = NULL;
|
||||
connection->n_slots = 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -122,6 +122,16 @@ void dbus_connection_unregister_handler (DBusConnection *connection,
|
|||
const char **messages_to_handle,
|
||||
int n_messages);
|
||||
|
||||
|
||||
int dbus_connection_allocate_data_slot (void);
|
||||
void dbus_connection_free_data_slot (int slot);
|
||||
dbus_bool_t dbus_connection_set_data (DBusConnection *connection,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func);
|
||||
void* dbus_connection_get_data (DBusConnection *connection,
|
||||
int slot);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
#endif /* DBUS_CONNECTION_H */
|
||||
|
|
|
|||
109
dbus/dbus-hash.c
109
dbus/dbus-hash.c
|
|
@ -220,7 +220,7 @@ typedef struct
|
|||
int n_entries_on_init; /**< used to detect table resize since initialization */
|
||||
} DBusRealHashIter;
|
||||
|
||||
static DBusHashEntry* find_int_function (DBusHashTable *table,
|
||||
static DBusHashEntry* find_direct_function (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashEntry ***bucket);
|
||||
|
|
@ -310,7 +310,8 @@ _dbus_hash_table_new (DBusHashType type,
|
|||
switch (table->key_type)
|
||||
{
|
||||
case DBUS_HASH_INT:
|
||||
table->find_function = find_int_function;
|
||||
case DBUS_HASH_POINTER:
|
||||
table->find_function = find_direct_function;
|
||||
break;
|
||||
case DBUS_HASH_STRING:
|
||||
table->find_function = find_string_function;
|
||||
|
|
@ -808,10 +809,10 @@ find_string_function (DBusHashTable *table,
|
|||
}
|
||||
|
||||
static DBusHashEntry*
|
||||
find_int_function (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashEntry ***bucket)
|
||||
find_direct_function (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashEntry ***bucket)
|
||||
{
|
||||
DBusHashEntry *entry;
|
||||
unsigned int idx;
|
||||
|
|
@ -940,6 +941,7 @@ rebuild_table (DBusHashTable *table)
|
|||
idx = string_hash (entry->key) & table->mask;
|
||||
break;
|
||||
case DBUS_HASH_INT:
|
||||
case DBUS_HASH_POINTER:
|
||||
idx = RANDOM_INDEX (table, entry->key);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1010,6 +1012,31 @@ _dbus_hash_table_lookup_int (DBusHashTable *table,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the value for a given integer in a hash table
|
||||
* of type #DBUS_HASH_POINTER. Returns %NULL if the value
|
||||
* is not present. (A not-present entry is indistinguishable
|
||||
* from an entry with a value of %NULL.)
|
||||
* @param table the hash table.
|
||||
* @param key the integer to look up.
|
||||
* @returns the value of the hash entry.
|
||||
*/
|
||||
void*
|
||||
_dbus_hash_table_lookup_pointer (DBusHashTable *table,
|
||||
void *key)
|
||||
{
|
||||
DBusHashEntry *entry;
|
||||
|
||||
_dbus_assert (table->key_type == DBUS_HASH_POINTER);
|
||||
|
||||
entry = (* table->find_function) (table, key, FALSE, NULL);
|
||||
|
||||
if (entry)
|
||||
return entry->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the hash entry for the given key. If no hash entry
|
||||
* for the key exists, does nothing.
|
||||
|
|
@ -1066,6 +1093,35 @@ _dbus_hash_table_remove_int (DBusHashTable *table,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the hash entry for the given key. If no hash entry
|
||||
* for the key exists, does nothing.
|
||||
*
|
||||
* @param table the hash table.
|
||||
* @param key the hash key.
|
||||
* @returns #TRUE if the entry existed
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_hash_table_remove_pointer (DBusHashTable *table,
|
||||
void *key)
|
||||
{
|
||||
DBusHashEntry *entry;
|
||||
DBusHashEntry **bucket;
|
||||
|
||||
_dbus_assert (table->key_type == DBUS_HASH_POINTER);
|
||||
|
||||
entry = (* table->find_function) (table, key, FALSE, &bucket);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
remove_entry (table, bucket, entry);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a hash entry with the given key and value.
|
||||
* The key and value are not copied; they are stored
|
||||
|
|
@ -1148,6 +1204,47 @@ _dbus_hash_table_insert_int (DBusHashTable *table,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hash entry with the given key and value.
|
||||
* The key and value are not copied; they are stored
|
||||
* in the hash table by reference. If an entry with the
|
||||
* given key already exists, the previous key and value
|
||||
* are overwritten (and freed if the hash table has
|
||||
* a key_free_function and/or value_free_function).
|
||||
*
|
||||
* Returns #FALSE if memory for the new hash entry
|
||||
* can't be allocated.
|
||||
*
|
||||
* @param table the hash table.
|
||||
* @param key the hash entry key.
|
||||
* @param value the hash entry value.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_hash_table_insert_pointer (DBusHashTable *table,
|
||||
void *key,
|
||||
void *value)
|
||||
{
|
||||
DBusHashEntry *entry;
|
||||
|
||||
_dbus_assert (table->key_type == DBUS_HASH_POINTER);
|
||||
|
||||
entry = (* table->find_function) (table, key, TRUE, NULL);
|
||||
|
||||
if (entry == NULL)
|
||||
return FALSE; /* no memory */
|
||||
|
||||
if (table->free_key_function && entry->key != key)
|
||||
(* table->free_key_function) (entry->key);
|
||||
|
||||
if (table->free_value_function && entry->value != value)
|
||||
(* table->free_value_function) (entry->value);
|
||||
|
||||
entry->key = key;
|
||||
entry->value = value;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of hash entries in a hash table.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ typedef struct DBusHashIter DBusHashIter;
|
|||
typedef enum
|
||||
{
|
||||
DBUS_HASH_STRING, /**< Hash keys are strings. */
|
||||
DBUS_HASH_INT /**< Hash keys are integers. */
|
||||
DBUS_HASH_INT, /**< Hash keys are integers. */
|
||||
DBUS_HASH_POINTER /**< Hash keys are pointers. */
|
||||
} DBusHashType;
|
||||
|
||||
DBusHashTable* _dbus_hash_table_new (DBusHashType type,
|
||||
|
|
@ -66,33 +67,39 @@ void _dbus_hash_iter_init (DBusHashTable *table,
|
|||
DBusHashIter *iter);
|
||||
dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
|
||||
|
||||
void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
|
||||
void* _dbus_hash_iter_get_value (DBusHashIter *iter);
|
||||
void _dbus_hash_iter_set_value (DBusHashIter *iter,
|
||||
void *value);
|
||||
int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
|
||||
const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
|
||||
void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
|
||||
void* _dbus_hash_iter_get_value (DBusHashIter *iter);
|
||||
void _dbus_hash_iter_set_value (DBusHashIter *iter,
|
||||
void *value);
|
||||
int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
|
||||
const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
|
||||
dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashIter *iter);
|
||||
void* _dbus_hash_table_lookup_string (DBusHashTable *table,
|
||||
const char *key);
|
||||
void* _dbus_hash_table_lookup_int (DBusHashTable *table,
|
||||
int key);
|
||||
void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
|
||||
void *key);
|
||||
dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
|
||||
const char *key);
|
||||
dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
|
||||
int key);
|
||||
dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
|
||||
void *key);
|
||||
dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
|
||||
char *key,
|
||||
void *value);
|
||||
dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
|
||||
int key,
|
||||
void *value);
|
||||
dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
|
||||
void *key,
|
||||
void *value);
|
||||
int _dbus_hash_table_get_n_entries (DBusHashTable *table);
|
||||
|
||||
dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
|
||||
void *key,
|
||||
dbus_bool_t create_if_not_found,
|
||||
DBusHashIter *iter);
|
||||
|
||||
void* _dbus_hash_table_lookup_string (DBusHashTable *table,
|
||||
const char *key);
|
||||
void* _dbus_hash_table_lookup_int (DBusHashTable *table,
|
||||
int key);
|
||||
dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
|
||||
const char *key);
|
||||
dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
|
||||
int key);
|
||||
dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
|
||||
char *key,
|
||||
void *value);
|
||||
dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
|
||||
int key,
|
||||
void *value);
|
||||
int _dbus_hash_table_get_n_entries (DBusHashTable *table);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ static DBusThreadFunctions thread_functions =
|
|||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static DBusMutex *static_mutex_init_lock = NULL;
|
||||
|
||||
/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */
|
||||
#define _DBUS_DUMMY_MUTEX ((void*)0xABCDEF)
|
||||
|
||||
/**
|
||||
* @defgroup DBusThreads Thread functions
|
||||
* @ingroup DBus
|
||||
|
|
@ -56,7 +61,7 @@ dbus_mutex_new (void)
|
|||
if (thread_functions.mutex_new)
|
||||
return (* thread_functions.mutex_new) ();
|
||||
else
|
||||
return NULL;
|
||||
return _DBUS_DUMMY_MUTEX;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,9 +111,13 @@ dbus_mutex_unlock (DBusMutex *mutex)
|
|||
* in efficiency. Note that this function must be called
|
||||
* BEFORE using any other D-BUS functions.
|
||||
*
|
||||
* @todo right now this function can only be called once,
|
||||
* maybe we should instead silently ignore multiple calls.
|
||||
*
|
||||
* @param functions functions for using threads
|
||||
* @returns #TRUE on success, #FALSE if no memory
|
||||
*/
|
||||
void
|
||||
dbus_bool_t
|
||||
dbus_threads_init (const DBusThreadFunctions *functions)
|
||||
{
|
||||
_dbus_assert (functions != NULL);
|
||||
|
|
@ -134,7 +143,7 @@ dbus_threads_init (const DBusThreadFunctions *functions)
|
|||
if (thread_functions.mask != 0)
|
||||
{
|
||||
_dbus_warn ("dbus_threads_init() may only be called one time\n");
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
thread_functions.mutex_new = functions->mutex_new;
|
||||
|
|
@ -143,6 +152,60 @@ dbus_threads_init (const DBusThreadFunctions *functions)
|
|||
thread_functions.mutex_unlock = functions->mutex_unlock;
|
||||
|
||||
thread_functions.mask = functions->mask;
|
||||
|
||||
static_mutex_init_lock = dbus_mutex_new ();
|
||||
|
||||
if (static_mutex_init_lock == NULL)
|
||||
{
|
||||
thread_functions.mask = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Accesses the field of DBusStaticMutex that
|
||||
* stores the DBusMutex used to implement.
|
||||
*/
|
||||
#define _DBUS_STATIC_MUTEX_IMPL(mutex) ((mutex)->pad1)
|
||||
|
||||
/**
|
||||
* Lock a static mutex
|
||||
*
|
||||
* @param mutex the mutex to lock
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_static_mutex_lock (DBusStaticMutex *mutex)
|
||||
{
|
||||
if (_DBUS_STATIC_MUTEX_IMPL (mutex))
|
||||
return dbus_mutex_lock (_DBUS_STATIC_MUTEX_IMPL (mutex));
|
||||
|
||||
if (!dbus_mutex_lock (static_mutex_init_lock))
|
||||
return FALSE;
|
||||
|
||||
if (_DBUS_STATIC_MUTEX_IMPL (mutex) == NULL)
|
||||
_DBUS_STATIC_MUTEX_IMPL (mutex) = dbus_mutex_new ();
|
||||
|
||||
dbus_mutex_unlock (static_mutex_init_lock);
|
||||
|
||||
if (_DBUS_STATIC_MUTEX_IMPL (mutex))
|
||||
return dbus_mutex_lock (_DBUS_STATIC_MUTEX_IMPL (mutex));
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock a static mutex
|
||||
* @param mutex the mutex to lock
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_static_mutex_unlock (DBusStaticMutex *mutex)
|
||||
{
|
||||
_dbus_assert (_DBUS_STATIC_MUTEX_IMPL (mutex) != NULL);
|
||||
|
||||
return dbus_mutex_unlock (_DBUS_STATIC_MUTEX_IMPL (mutex));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -75,7 +75,22 @@ void dbus_mutex_free (DBusMutex *mutex);
|
|||
dbus_bool_t dbus_mutex_lock (DBusMutex *mutex);
|
||||
dbus_bool_t dbus_mutex_unlock (DBusMutex *mutex);
|
||||
|
||||
void dbus_threads_init (const DBusThreadFunctions *functions);
|
||||
dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions);
|
||||
|
||||
typedef struct DBusStaticMutex DBusStaticMutex;
|
||||
|
||||
struct DBusStaticMutex
|
||||
{
|
||||
void *pad1;
|
||||
void *pad2;
|
||||
void *pad3;
|
||||
void *pad4;
|
||||
};
|
||||
|
||||
#define DBUS_STATIC_MUTEX_INIT { NULL, NULL, NULL, NULL }
|
||||
|
||||
dbus_bool_t dbus_static_mutex_lock (DBusStaticMutex *mutex);
|
||||
dbus_bool_t dbus_static_mutex_unlock (DBusStaticMutex *mutex);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue