mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-08 17:18:27 +02:00
2003-02-26 Havoc Pennington <hp@pobox.com>
* dbus/dbus-connection.c (dbus_connection_send_message_with_reply_and_block): fix crash where we ref'd the outgoing message instead of the returned reply * dbus/dbus-transport-unix.c (do_authentication): check read watch at the end of this function, so if we didn't need to read for authentication, we reinstall it for receiving messages * dbus/dbus-message.c (dbus_message_new_reply): allow replies to a NULL sender for peer-to-peer case * dbus/dbus-transport-unix.c (check_read_watch): handle !authenticated case correctly * glib/dbus-gmain.c: add support for DBusServer * dbus/dbus-server.c: add data slot support * glib/dbus-gmain.c (dbus_connection_setup_with_g_main): check return values and handle errors * dbus/dbus-dataslot.c: factor out the data slot stuff from DBusConnection * Doxyfile.in (INPUT): add glib subdir * glib/dbus-gmain.c (dbus_connection_setup_with_g_main): rename setup_with_g_main instead of hookup_with_g_main; write docs
This commit is contained in:
parent
3781f063a6
commit
7265423411
21 changed files with 1038 additions and 245 deletions
31
ChangeLog
31
ChangeLog
|
|
@ -1,3 +1,34 @@
|
|||
2003-02-26 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* dbus/dbus-connection.c
|
||||
(dbus_connection_send_message_with_reply_and_block): fix crash
|
||||
where we ref'd the outgoing message instead of the returned reply
|
||||
|
||||
* dbus/dbus-transport-unix.c (do_authentication): check read watch
|
||||
at the end of this function, so if we didn't need to read for
|
||||
authentication, we reinstall it for receiving messages
|
||||
|
||||
* dbus/dbus-message.c (dbus_message_new_reply): allow replies to
|
||||
a NULL sender for peer-to-peer case
|
||||
|
||||
* dbus/dbus-transport-unix.c (check_read_watch): handle
|
||||
!authenticated case correctly
|
||||
|
||||
* glib/dbus-gmain.c: add support for DBusServer
|
||||
|
||||
* dbus/dbus-server.c: add data slot support
|
||||
|
||||
* glib/dbus-gmain.c (dbus_connection_setup_with_g_main): check
|
||||
return values and handle errors
|
||||
|
||||
* dbus/dbus-dataslot.c: factor out the data slot stuff from
|
||||
DBusConnection
|
||||
|
||||
* Doxyfile.in (INPUT): add glib subdir
|
||||
|
||||
* glib/dbus-gmain.c (dbus_connection_setup_with_g_main): rename
|
||||
setup_with_g_main instead of hookup_with_g_main; write docs
|
||||
|
||||
2003-02-24 Anders Carlsson <andersca@codefactory.se>
|
||||
|
||||
* dbus/dbus-marshal.c: (_dbus_marshal_validate_arg):
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ WARN_LOGFILE =
|
|||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = dbus bus
|
||||
INPUT = dbus bus glib
|
||||
FILE_PATTERNS = *.c *.h
|
||||
RECURSIVE = YES
|
||||
#EXCLUDE = test
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ libdbus_1_la_SOURCES= \
|
|||
noinst_LTLIBRARIES=libdbus-convenience.la
|
||||
|
||||
libdbus_convenience_la_SOURCES= \
|
||||
dbus-dataslot.c \
|
||||
dbus-dataslot.h \
|
||||
dbus-hash.c \
|
||||
dbus-hash.h \
|
||||
dbus-internals.c \
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "dbus-message-handler.h"
|
||||
#include "dbus-threads.h"
|
||||
#include "dbus-protocol.h"
|
||||
#include "dbus-dataslot.h"
|
||||
|
||||
/**
|
||||
* @defgroup DBusConnection DBusConnection
|
||||
|
|
@ -66,15 +67,6 @@
|
|||
|
||||
static dbus_bool_t _dbus_modify_sigpipe = TRUE;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
|
|
@ -105,8 +97,8 @@ struct DBusConnection
|
|||
|
||||
DBusHashTable *handler_table; /**< Table of registered DBusMessageHandler */
|
||||
DBusList *filter_list; /**< List of filters. */
|
||||
DBusDataSlot *data_slots; /**< Data slots */
|
||||
int n_slots; /**< Slots allocated so far. */
|
||||
|
||||
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
|
||||
|
||||
DBusHashTable *pending_replies; /**< Hash of message serials and their message handlers. */
|
||||
DBusCounter *connection_counter; /**< Counter that we decrement when finalized */
|
||||
|
|
@ -130,7 +122,6 @@ typedef struct
|
|||
|
||||
static void reply_handler_data_free (ReplyHandlerData *data);
|
||||
|
||||
static void _dbus_connection_free_data_slots_nolock (DBusConnection *connection);
|
||||
static void _dbus_connection_remove_timeout_locked (DBusConnection *connection,
|
||||
DBusTimeout *timeout);
|
||||
|
||||
|
|
@ -572,8 +563,8 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
|
|||
connection->pending_replies = pending_replies;
|
||||
connection->filter_list = NULL;
|
||||
|
||||
connection->data_slots = NULL;
|
||||
connection->n_slots = 0;
|
||||
_dbus_data_slot_list_init (&connection->slot_list);
|
||||
|
||||
connection->client_serial = 1;
|
||||
|
||||
connection->disconnect_message_link = disconnect_link;
|
||||
|
|
@ -798,8 +789,9 @@ _dbus_connection_last_unref (DBusConnection *connection)
|
|||
|
||||
_dbus_timeout_list_free (connection->timeouts);
|
||||
connection->timeouts = NULL;
|
||||
|
||||
_dbus_connection_free_data_slots_nolock (connection);
|
||||
|
||||
/* calls out to application code... */
|
||||
_dbus_data_slot_list_free (&connection->slot_list);
|
||||
|
||||
_dbus_hash_iter_init (connection->handler_table, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
|
|
@ -1078,6 +1070,10 @@ reply_handler_data_free (ReplyHandlerData *data)
|
|||
* you want a very short or very long timeout. There is no way to
|
||||
* avoid a timeout entirely, other than passing INT_MAX for the
|
||||
* timeout to postpone it indefinitely.
|
||||
*
|
||||
* @todo I think we should rename this function family
|
||||
* dbus_connection_send(), send_with_reply(), etc. (i.e.
|
||||
* drop the "message" part), the names are too long.
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param message the message to send
|
||||
|
|
@ -1086,13 +1082,6 @@ reply_handler_data_free (ReplyHandlerData *data)
|
|||
* @param result return location for result code
|
||||
* @returns #TRUE if the message is successfully queued, #FALSE if no memory.
|
||||
*
|
||||
* @todo this function isn't implemented because we need message serials
|
||||
* and other slightly more rich DBusMessage implementation in order to
|
||||
* implement it. The basic idea will be to keep a hash of serials we're
|
||||
* expecting a reply to, and also to add a way to tell GLib or Qt to
|
||||
* install a timeout. Then install a timeout which is the shortest
|
||||
* timeout of any pending reply.
|
||||
*
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_connection_send_message_with_reply (DBusConnection *connection,
|
||||
|
|
@ -1227,10 +1216,9 @@ dbus_connection_send_message_with_reply (DBusConnection *connection,
|
|||
* wrong, result is set to whatever is appropriate, such as
|
||||
* #DBUS_RESULT_NO_MEMORY.
|
||||
*
|
||||
* @todo I believe if we get EINTR or otherwise interrupt the
|
||||
* do_iteration call in here, we won't block the required length of
|
||||
* time. I think there probably has to be a loop: "while (!timeout_elapsed)
|
||||
* { check_for_reply_in_queue(); iterate_with_remaining_timeout(); }"
|
||||
* @todo could use performance improvements (it keeps scanning
|
||||
* the whole message queue for example) and has thread issues,
|
||||
* see comments in source
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param message the message to send
|
||||
|
|
@ -1247,22 +1235,47 @@ dbus_connection_send_message_with_reply_and_block (DBusConnection *connectio
|
|||
{
|
||||
dbus_int32_t client_serial;
|
||||
DBusList *link;
|
||||
long start_tv_sec, start_tv_usec;
|
||||
long end_tv_sec, end_tv_usec;
|
||||
long tv_sec, tv_usec;
|
||||
|
||||
if (timeout_milliseconds == -1)
|
||||
timeout_milliseconds = DEFAULT_TIMEOUT_VALUE;
|
||||
|
||||
/* it would probably seem logical to pass in _DBUS_INT_MAX
|
||||
* for infinite timeout, but then math below would get
|
||||
* all overflow-prone, so smack that down.
|
||||
*/
|
||||
if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
|
||||
timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
|
||||
|
||||
if (!dbus_connection_send_message (connection, message, &client_serial, result))
|
||||
return NULL;
|
||||
|
||||
message = NULL;
|
||||
|
||||
/* Flush message queue */
|
||||
dbus_connection_flush (connection);
|
||||
|
||||
dbus_mutex_lock (connection->mutex);
|
||||
|
||||
_dbus_get_current_time (&start_tv_sec, &start_tv_usec);
|
||||
end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
|
||||
end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
|
||||
end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
|
||||
end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
|
||||
|
||||
_dbus_verbose ("will block %d milliseconds from %ld sec %ld usec to %ld sec %ld usec\n",
|
||||
timeout_milliseconds,
|
||||
start_tv_sec, start_tv_usec,
|
||||
end_tv_sec, end_tv_usec);
|
||||
|
||||
/* Now we wait... */
|
||||
/* THREAD TODO: This is busted. What if a dispatch_message or pop_message
|
||||
* gets the message before we do?
|
||||
*/
|
||||
block_again:
|
||||
|
||||
_dbus_connection_do_iteration (connection,
|
||||
DBUS_ITERATION_DO_READING |
|
||||
DBUS_ITERATION_BLOCK,
|
||||
|
|
@ -1278,7 +1291,7 @@ dbus_connection_send_message_with_reply_and_block (DBusConnection *connectio
|
|||
if (_dbus_message_get_reply_serial (reply) == client_serial)
|
||||
{
|
||||
_dbus_list_remove (&connection->incoming_messages, link);
|
||||
dbus_message_ref (message);
|
||||
dbus_message_ref (reply);
|
||||
|
||||
if (result)
|
||||
*result = DBUS_RESULT_SUCCESS;
|
||||
|
|
@ -1289,8 +1302,27 @@ dbus_connection_send_message_with_reply_and_block (DBusConnection *connectio
|
|||
link = _dbus_list_get_next_link (&connection->incoming_messages, link);
|
||||
}
|
||||
|
||||
if (result)
|
||||
*result = DBUS_RESULT_NO_REPLY;
|
||||
_dbus_get_current_time (&tv_sec, &tv_usec);
|
||||
|
||||
if (tv_sec < start_tv_sec)
|
||||
; /* clock set backward, bail out */
|
||||
else if (connection->disconnect_message_link == NULL)
|
||||
; /* we're disconnected, bail out */
|
||||
else if (tv_sec < end_tv_sec ||
|
||||
(tv_sec == end_tv_sec && tv_usec < end_tv_usec))
|
||||
{
|
||||
timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
|
||||
(end_tv_usec - tv_usec) / 1000;
|
||||
_dbus_verbose ("%d milliseconds remain\n", timeout_milliseconds);
|
||||
_dbus_assert (timeout_milliseconds > 0);
|
||||
|
||||
goto block_again; /* not expired yet */
|
||||
}
|
||||
|
||||
if (dbus_connection_get_is_connected (connection))
|
||||
dbus_set_result (result, DBUS_RESULT_NO_REPLY);
|
||||
else
|
||||
dbus_set_result (result, DBUS_RESULT_DISCONNECTED);
|
||||
|
||||
dbus_mutex_unlock (connection->mutex);
|
||||
|
||||
|
|
@ -1850,6 +1882,12 @@ dbus_connection_remove_filter (DBusConnection *connection,
|
|||
* this function with the name of a message that already has a
|
||||
* handler. If the function returns #FALSE, the handlers were not
|
||||
* registered due to lack of memory.
|
||||
*
|
||||
* @todo the messages_to_handle arg may be more convenient if it's a
|
||||
* single string instead of an array. Though right now MessageHandler
|
||||
* is sort of designed to say be associated with an entire object with
|
||||
* multiple methods, that's why for example the connection only
|
||||
* weakrefs it. So maybe the "manual" API should be different.
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param handler the handler
|
||||
|
|
@ -1969,25 +2007,23 @@ dbus_connection_unregister_handler (DBusConnection *connection,
|
|||
dbus_mutex_unlock (connection->mutex);
|
||||
}
|
||||
|
||||
static int *allocated_slots = NULL;
|
||||
static int n_allocated_slots = 0;
|
||||
static int n_used_slots = 0;
|
||||
static DBusMutex *allocated_slots_lock = NULL;
|
||||
static DBusDataSlotAllocator slot_allocator;
|
||||
|
||||
/**
|
||||
* Initialize the mutex used for #DBusConnecton data
|
||||
* Initialize the mutex used for #DBusConnection data
|
||||
* slot reservations.
|
||||
*
|
||||
* @returns the mutex
|
||||
*/
|
||||
DBusMutex *
|
||||
_dbus_allocated_slots_init_lock (void)
|
||||
_dbus_connection_slots_init_lock (void)
|
||||
{
|
||||
allocated_slots_lock = dbus_mutex_new ();
|
||||
return allocated_slots_lock;
|
||||
if (!_dbus_data_slot_allocator_init (&slot_allocator))
|
||||
return NULL;
|
||||
else
|
||||
return slot_allocator.lock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocates an integer ID to be used for storing application-specific
|
||||
* data on any DBusConnection. The allocated ID may then be used
|
||||
|
|
@ -2001,50 +2037,7 @@ _dbus_allocated_slots_init_lock (void)
|
|||
int
|
||||
dbus_connection_allocate_data_slot (void)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if (!dbus_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_mutex_unlock (allocated_slots_lock);
|
||||
return slot;
|
||||
return _dbus_data_slot_allocator_alloc (&slot_allocator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2061,22 +2054,7 @@ dbus_connection_allocate_data_slot (void)
|
|||
void
|
||||
dbus_connection_free_data_slot (int slot)
|
||||
{
|
||||
dbus_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_mutex_unlock (allocated_slots_lock);
|
||||
_dbus_data_slot_allocator_free (&slot_allocator, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2100,50 +2078,25 @@ dbus_connection_set_data (DBusConnection *connection,
|
|||
{
|
||||
DBusFreeFunction old_free_func;
|
||||
void *old_data;
|
||||
dbus_bool_t retval;
|
||||
|
||||
dbus_mutex_lock (connection->mutex);
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
_dbus_assert (allocated_slots[slot] == slot);
|
||||
|
||||
retval = _dbus_data_slot_list_set (&slot_allocator,
|
||||
&connection->slot_list,
|
||||
slot, data, free_data_func,
|
||||
&old_free_func, &old_data);
|
||||
|
||||
if (slot >= connection->n_slots)
|
||||
{
|
||||
DBusDataSlot *tmp;
|
||||
int i;
|
||||
|
||||
tmp = dbus_realloc (connection->data_slots,
|
||||
sizeof (DBusDataSlot) * (slot + 1));
|
||||
if (tmp == NULL)
|
||||
{
|
||||
dbus_mutex_unlock (connection->mutex);
|
||||
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);
|
||||
|
||||
old_data = connection->data_slots[slot].data;
|
||||
old_free_func = connection->data_slots[slot].free_data_func;
|
||||
|
||||
connection->data_slots[slot].data = data;
|
||||
connection->data_slots[slot].free_data_func = free_data_func;
|
||||
|
||||
dbus_mutex_unlock (connection->mutex);
|
||||
|
||||
/* Do the actual free outside the connection lock */
|
||||
if (old_free_func)
|
||||
(* old_free_func) (old_data);
|
||||
if (retval)
|
||||
{
|
||||
/* Do the actual free outside the connection lock */
|
||||
if (old_free_func)
|
||||
(* old_free_func) (old_data);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2161,15 +2114,11 @@ dbus_connection_get_data (DBusConnection *connection,
|
|||
void *res;
|
||||
|
||||
dbus_mutex_lock (connection->mutex);
|
||||
|
||||
res = _dbus_data_slot_list_get (&slot_allocator,
|
||||
&connection->slot_list,
|
||||
slot);
|
||||
|
||||
_dbus_assert (slot < n_allocated_slots);
|
||||
_dbus_assert (allocated_slots[slot] == slot);
|
||||
|
||||
if (slot >= connection->n_slots)
|
||||
res = NULL;
|
||||
else
|
||||
res = connection->data_slots[slot].data;
|
||||
|
||||
dbus_mutex_unlock (connection->mutex);
|
||||
|
||||
return res;
|
||||
|
|
@ -2187,30 +2136,6 @@ dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
|
|||
_dbus_modify_sigpipe = will_modify_sigpipe;
|
||||
}
|
||||
|
||||
/* This must be called with the connection lock not held to avoid
|
||||
* holding it over the free_data callbacks, so it can basically
|
||||
* only be called at last unref
|
||||
*/
|
||||
static void
|
||||
_dbus_connection_free_data_slots_nolock (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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the maximum size message this connection is allowed to
|
||||
* receive. Larger messages will result in disconnecting the
|
||||
|
|
|
|||
372
dbus/dbus-dataslot.c
Normal file
372
dbus/dbus-dataslot.c
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-dataslot.c storing data on objects
|
||||
*
|
||||
* 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 "dbus-dataslot.h"
|
||||
#include "dbus-threads.h"
|
||||
|
||||
/**
|
||||
* @defgroup DBusDataSlot Data slots
|
||||
* @ingroup DBusInternals
|
||||
* @brief Storing data by ID
|
||||
*
|
||||
* Types and functions related to storing data by an
|
||||
* allocated ID. This is used for dbus_connection_set_data(),
|
||||
* dbus_server_set_data(), etc.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initializes a data slot allocator object, used to assign
|
||||
* integer IDs for data slots.
|
||||
*
|
||||
* @param allocator the allocator to initialize
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator)
|
||||
{
|
||||
allocator->allocated_slots = NULL;
|
||||
allocator->n_allocated_slots = 0;
|
||||
allocator->n_used_slots = 0;
|
||||
allocator->lock = dbus_mutex_new ();
|
||||
if (allocator->lock == NULL)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates an integer ID to be used for storing data
|
||||
* in a #DBusDataSlotList.
|
||||
*
|
||||
* @param allocator the allocator
|
||||
* @returns the integer ID, or -1 on failure
|
||||
*/
|
||||
int
|
||||
_dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator)
|
||||
{
|
||||
int slot;
|
||||
|
||||
if (!dbus_mutex_lock (allocator->lock))
|
||||
return -1;
|
||||
|
||||
if (allocator->n_used_slots < allocator->n_allocated_slots)
|
||||
{
|
||||
slot = 0;
|
||||
while (slot < allocator->n_allocated_slots)
|
||||
{
|
||||
if (allocator->allocated_slots[slot] < 0)
|
||||
{
|
||||
allocator->allocated_slots[slot] = slot;
|
||||
allocator->n_used_slots += 1;
|
||||
break;
|
||||
}
|
||||
++slot;
|
||||
}
|
||||
|
||||
_dbus_assert (slot < allocator->n_allocated_slots);
|
||||
}
|
||||
else
|
||||
{
|
||||
int *tmp;
|
||||
|
||||
slot = -1;
|
||||
tmp = dbus_realloc (allocator->allocated_slots,
|
||||
sizeof (int) * (allocator->n_allocated_slots + 1));
|
||||
if (tmp == NULL)
|
||||
goto out;
|
||||
|
||||
allocator->allocated_slots = tmp;
|
||||
slot = allocator->n_allocated_slots;
|
||||
allocator->n_allocated_slots += 1;
|
||||
allocator->n_used_slots += 1;
|
||||
allocator->allocated_slots[slot] = slot;
|
||||
}
|
||||
|
||||
_dbus_assert (slot >= 0);
|
||||
_dbus_assert (slot < allocator->n_allocated_slots);
|
||||
|
||||
out:
|
||||
dbus_mutex_unlock (allocator->lock);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates an ID previously allocated with
|
||||
* _dbus_data_slot_allocator_alloc(). Existing data stored on
|
||||
* 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).
|
||||
*
|
||||
* @param allocator the allocator
|
||||
* @param slot the slot to deallocate
|
||||
*/
|
||||
void
|
||||
_dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
|
||||
int slot)
|
||||
{
|
||||
dbus_mutex_lock (allocator->lock);
|
||||
|
||||
_dbus_assert (slot < allocator->n_allocated_slots);
|
||||
_dbus_assert (allocator->allocated_slots[slot] == slot);
|
||||
|
||||
allocator->allocated_slots[slot] = -1;
|
||||
allocator->n_used_slots -= 1;
|
||||
|
||||
if (allocator->n_used_slots == 0)
|
||||
{
|
||||
dbus_free (allocator->allocated_slots);
|
||||
allocator->allocated_slots = NULL;
|
||||
allocator->n_allocated_slots = 0;
|
||||
}
|
||||
|
||||
dbus_mutex_unlock (allocator->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a slot list.
|
||||
* @param list the list to initialize.
|
||||
*/
|
||||
void
|
||||
_dbus_data_slot_list_init (DBusDataSlotList *list)
|
||||
{
|
||||
list->slots = NULL;
|
||||
list->n_slots = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a pointer in the data slot list, along with an optional
|
||||
* function to be used for freeing the data when the data is set
|
||||
* again, or when the slot list is finalized. The slot number must
|
||||
* have been allocated with _dbus_data_slot_allocator_alloc() for the
|
||||
* same allocator passed in here. The same allocator has to be used
|
||||
* with the slot list every time.
|
||||
*
|
||||
* @param allocator the allocator to use
|
||||
* @param list the data slot list
|
||||
* @param slot the slot number
|
||||
* @param data the data to store
|
||||
* @param free_data_func finalizer function for the data
|
||||
* @param old_free_func free function for any previously-existing data
|
||||
* @param old_data previously-existing data, should be freed with old_free_func
|
||||
* @returns #TRUE if there was enough memory to store the data
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_data_slot_list_set (DBusDataSlotAllocator *allocator,
|
||||
DBusDataSlotList *list,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func,
|
||||
DBusFreeFunction *old_free_func,
|
||||
void **old_data)
|
||||
{
|
||||
_dbus_assert (slot < allocator->n_allocated_slots);
|
||||
_dbus_assert (allocator->allocated_slots[slot] == slot);
|
||||
|
||||
if (slot >= list->n_slots)
|
||||
{
|
||||
DBusDataSlot *tmp;
|
||||
int i;
|
||||
|
||||
tmp = dbus_realloc (list->slots,
|
||||
sizeof (DBusDataSlot) * (slot + 1));
|
||||
if (tmp == NULL)
|
||||
return FALSE;
|
||||
|
||||
list->slots = tmp;
|
||||
i = list->n_slots;
|
||||
list->n_slots = slot + 1;
|
||||
while (i < list->n_slots)
|
||||
{
|
||||
list->slots[i].data = NULL;
|
||||
list->slots[i].free_data_func = NULL;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
_dbus_assert (slot < list->n_slots);
|
||||
|
||||
*old_data = list->slots[slot].data;
|
||||
*old_free_func = list->slots[slot].free_data_func;
|
||||
|
||||
list->slots[slot].data = data;
|
||||
list->slots[slot].free_data_func = free_data_func;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data previously set with _dbus_data_slot_list_set_data().
|
||||
* The slot must still be allocated (must not have been freed).
|
||||
*
|
||||
* @param allocator the allocator slot was allocated from
|
||||
* @param list the data slot list
|
||||
* @param slot the slot to get data from
|
||||
* @returns the data, or #NULL if not found
|
||||
*/
|
||||
void*
|
||||
_dbus_data_slot_list_get (DBusDataSlotAllocator *allocator,
|
||||
DBusDataSlotList *list,
|
||||
int slot)
|
||||
{
|
||||
_dbus_assert (slot < allocator->n_allocated_slots);
|
||||
_dbus_assert (allocator->allocated_slots[slot] == slot);
|
||||
|
||||
if (slot >= list->n_slots)
|
||||
return NULL;
|
||||
else
|
||||
return list->slots[slot].data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the data slot list and all data slots contained
|
||||
* in it, calling application-provided free functions
|
||||
* if they exist.
|
||||
*
|
||||
* @param list the list to free
|
||||
*/
|
||||
void
|
||||
_dbus_data_slot_list_free (DBusDataSlotList *list)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < list->n_slots)
|
||||
{
|
||||
if (list->slots[i].free_data_func)
|
||||
(* list->slots[i].free_data_func) (list->slots[i].data);
|
||||
list->slots[i].data = NULL;
|
||||
list->slots[i].free_data_func = NULL;
|
||||
++i;
|
||||
}
|
||||
|
||||
dbus_free (list->slots);
|
||||
list->slots = NULL;
|
||||
list->n_slots = 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
#include "dbus-test.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static int free_counter;
|
||||
|
||||
static void
|
||||
test_free_slot_data_func (void *data)
|
||||
{
|
||||
int i = _DBUS_POINTER_TO_INT (data);
|
||||
|
||||
_dbus_assert (free_counter == i);
|
||||
++free_counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function for data slots
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_data_slot_test (void)
|
||||
{
|
||||
DBusDataSlotAllocator allocator;
|
||||
DBusDataSlotList list;
|
||||
int i;
|
||||
DBusFreeFunction old_free_func;
|
||||
void *old_data;
|
||||
|
||||
if (!_dbus_data_slot_allocator_init (&allocator))
|
||||
_dbus_assert_not_reached ("no memory for allocator");
|
||||
|
||||
_dbus_data_slot_list_init (&list);
|
||||
|
||||
#define N_SLOTS 100
|
||||
|
||||
i = 0;
|
||||
while (i < N_SLOTS)
|
||||
{
|
||||
/* we don't really want apps to rely on this ordered
|
||||
* allocation, but it simplifies things to rely on it
|
||||
* here.
|
||||
*/
|
||||
if (_dbus_data_slot_allocator_alloc (&allocator) != i)
|
||||
_dbus_assert_not_reached ("did not allocate slots in numeric order\n");
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < N_SLOTS)
|
||||
{
|
||||
if (!_dbus_data_slot_list_set (&allocator, &list,
|
||||
i,
|
||||
_DBUS_INT_TO_POINTER (i),
|
||||
test_free_slot_data_func,
|
||||
&old_free_func, &old_data))
|
||||
_dbus_assert_not_reached ("no memory to set data");
|
||||
|
||||
_dbus_assert (old_free_func == NULL);
|
||||
_dbus_assert (old_data == NULL);
|
||||
|
||||
_dbus_assert (_dbus_data_slot_list_get (&allocator, &list, i) ==
|
||||
_DBUS_INT_TO_POINTER (i));
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
free_counter = 0;
|
||||
i = 0;
|
||||
while (i < N_SLOTS)
|
||||
{
|
||||
if (!_dbus_data_slot_list_set (&allocator, &list,
|
||||
i,
|
||||
_DBUS_INT_TO_POINTER (i),
|
||||
test_free_slot_data_func,
|
||||
&old_free_func, &old_data))
|
||||
_dbus_assert_not_reached ("no memory to set data");
|
||||
|
||||
_dbus_assert (old_free_func == test_free_slot_data_func);
|
||||
_dbus_assert (_DBUS_POINTER_TO_INT (old_data) == i);
|
||||
|
||||
(* old_free_func) (old_data);
|
||||
_dbus_assert (i == (free_counter - 1));
|
||||
|
||||
_dbus_assert (_dbus_data_slot_list_get (&allocator, &list, i) ==
|
||||
_DBUS_INT_TO_POINTER (i));
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
free_counter = 0;
|
||||
_dbus_data_slot_list_free (&list);
|
||||
|
||||
_dbus_assert (N_SLOTS == free_counter);
|
||||
|
||||
i = 0;
|
||||
while (i < N_SLOTS)
|
||||
{
|
||||
_dbus_data_slot_allocator_free (&allocator, i);
|
||||
++i;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* DBUS_BUILD_TESTS */
|
||||
76
dbus/dbus-dataslot.h
Normal file
76
dbus/dbus-dataslot.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-dataslot.h storing data on objects
|
||||
*
|
||||
* 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 DBUS_DATASLOT_H
|
||||
#define DBUS_DATASLOT_H
|
||||
|
||||
#include <dbus/dbus-internals.h>
|
||||
|
||||
DBUS_BEGIN_DECLS;
|
||||
|
||||
typedef struct DBusDataSlotAllocator DBusDataSlotAllocator;
|
||||
typedef struct DBusDataSlotList DBusDataSlotList;
|
||||
|
||||
/** 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 */
|
||||
};
|
||||
|
||||
struct DBusDataSlotAllocator
|
||||
{
|
||||
int *allocated_slots; /**< Allocated slots */
|
||||
int n_allocated_slots; /**< number of slots malloc'd */
|
||||
int n_used_slots; /**< number of slots used */
|
||||
DBusMutex *lock; /**< thread lock */
|
||||
};
|
||||
|
||||
struct DBusDataSlotList
|
||||
{
|
||||
DBusDataSlot *slots; /**< Data slots */
|
||||
int n_slots; /**< Slots we have storage for in data_slots */
|
||||
};
|
||||
|
||||
dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator);
|
||||
int _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator);
|
||||
void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
|
||||
int slot_id);
|
||||
|
||||
void _dbus_data_slot_list_init (DBusDataSlotList *list);
|
||||
dbus_bool_t _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator,
|
||||
DBusDataSlotList *list,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func,
|
||||
DBusFreeFunction *old_free_func,
|
||||
void **old_data);
|
||||
void* _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator,
|
||||
DBusDataSlotList *list,
|
||||
int slot);
|
||||
void _dbus_data_slot_list_free (DBusDataSlotList *list);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
#endif /* DBUS_DATASLOT_H */
|
||||
|
|
@ -118,6 +118,8 @@ char* _dbus_strdup (const char *str);
|
|||
#define _DBUS_MAX_SUN_PATH_LENGTH 99
|
||||
#define _DBUS_ONE_KILOBYTE 1024
|
||||
#define _DBUS_ONE_MEGABYTE 1024 * _DBUS_ONE_KILOBYTE
|
||||
#define _DBUS_ONE_HOUR_IN_MILLISECONDS (1000 * 60 * 60)
|
||||
#define _DBUS_USEC_PER_SECOND (1000000)
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
|
@ -155,12 +157,12 @@ dbus_bool_t _dbus_decrement_fail_alloc_counter (void);
|
|||
#endif /* !DBUS_BUILD_TESTS */
|
||||
|
||||
/* Thread initializers */
|
||||
DBusMutex *_dbus_list_init_lock (void);
|
||||
DBusMutex *_dbus_allocated_slots_init_lock (void);
|
||||
DBusMutex *_dbus_atomic_init_lock (void);
|
||||
DBusMutex *_dbus_message_handler_init_lock (void);
|
||||
DBusMutex *_dbus_user_info_init_lock (void);
|
||||
|
||||
DBusMutex *_dbus_list_init_lock (void);
|
||||
DBusMutex *_dbus_connection_slots_init_lock (void);
|
||||
DBusMutex *_dbus_server_slots_init_lock (void);
|
||||
DBusMutex *_dbus_atomic_init_lock (void);
|
||||
DBusMutex *_dbus_message_handler_init_lock (void);
|
||||
DBusMutex *_dbus_user_info_init_lock (void);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ free_keys (DBusKey *keys,
|
|||
*/
|
||||
|
||||
/** Maximum number of timeouts waiting for lock before we decide it's stale */
|
||||
#define MAX_LOCK_TIMEOUTS 16
|
||||
#define MAX_LOCK_TIMEOUTS 32
|
||||
/** Length of each timeout while waiting for a lock */
|
||||
#define LOCK_TIMEOUT_MILLISECONDS 250
|
||||
|
||||
|
|
|
|||
|
|
@ -184,8 +184,12 @@ get_string_field (DBusMessage *message,
|
|||
int field,
|
||||
int *len)
|
||||
{
|
||||
int offset = message->header_fields[field].offset;
|
||||
int offset;
|
||||
const char *data;
|
||||
|
||||
offset = message->header_fields[field].offset;
|
||||
|
||||
_dbus_assert (field < FIELD_LAST);
|
||||
|
||||
if (offset < 0)
|
||||
return NULL;
|
||||
|
|
@ -209,13 +213,17 @@ get_string_field (DBusMessage *message,
|
|||
|
||||
static dbus_int32_t
|
||||
get_int_field (DBusMessage *message,
|
||||
int field)
|
||||
int field)
|
||||
{
|
||||
int offset = message->header_fields[field].offset;
|
||||
int offset;
|
||||
|
||||
_dbus_assert (field < FIELD_LAST);
|
||||
|
||||
offset = message->header_fields[field].offset;
|
||||
|
||||
if (offset < 0)
|
||||
return -1; /* useless if -1 is a valid value of course */
|
||||
|
||||
|
||||
return _dbus_demarshal_int32 (&message->header,
|
||||
message->byte_order,
|
||||
offset,
|
||||
|
|
@ -798,8 +806,8 @@ dbus_message_new_reply (DBusMessage *original_message)
|
|||
FIELD_SENDER, NULL);
|
||||
name = get_string_field (original_message,
|
||||
FIELD_NAME, NULL);
|
||||
|
||||
_dbus_assert (sender != NULL);
|
||||
|
||||
/* sender is allowed to be null here in peer-to-peer case */
|
||||
|
||||
message = dbus_message_new (sender, name);
|
||||
|
||||
|
|
@ -1703,6 +1711,10 @@ dbus_message_get_args_valist (DBusMessage *message,
|
|||
* ref/unref is kind of annoying to deal with, and slower too.
|
||||
* This implies not ref'ing the message from the iter.
|
||||
*
|
||||
* @todo I'd also name this dbus_message_iter_new() or
|
||||
* for the static object dbus_message_iter_init() rather
|
||||
* than making it a method on the message
|
||||
*
|
||||
* @param message the message
|
||||
* @returns a new iter.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <dbus/dbus-timeout.h>
|
||||
#include <dbus/dbus-watch.h>
|
||||
#include <dbus/dbus-resources.h>
|
||||
#include <dbus/dbus-dataslot.h>
|
||||
|
||||
DBUS_BEGIN_DECLS;
|
||||
|
||||
|
|
@ -61,6 +62,8 @@ struct DBusServer
|
|||
*/
|
||||
|
||||
int max_connections; /**< Max number of connections allowed at once. */
|
||||
|
||||
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
|
||||
|
||||
DBusNewConnectionFunction new_connection_function;
|
||||
/**< Callback to invoke when a new connection is created. */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-server.c DBusServer object
|
||||
*
|
||||
* Copyright (C) 2002 Red Hat Inc.
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
*
|
||||
* Licensed under the Academic Free License version 1.2
|
||||
*
|
||||
|
|
@ -37,6 +37,9 @@
|
|||
* A DBusServer represents a server that other applications
|
||||
* can connect to. Each connection from another application
|
||||
* is represented by a DBusConnection.
|
||||
*
|
||||
* @todo Thread safety hasn't been looked at for #DBusServer
|
||||
* @todo Need notification to apps of disconnection, may matter for some transports
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -86,6 +89,8 @@ _dbus_server_init_base (DBusServer *server,
|
|||
}
|
||||
|
||||
server->max_connections = 256; /* same as an X server, seems like a nice default */
|
||||
|
||||
_dbus_data_slot_list_init (&server->slot_list);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -99,6 +104,9 @@ _dbus_server_init_base (DBusServer *server,
|
|||
void
|
||||
_dbus_server_finalize_base (DBusServer *server)
|
||||
{
|
||||
/* calls out to application code... */
|
||||
_dbus_data_slot_list_free (&server->slot_list);
|
||||
|
||||
dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
|
||||
|
||||
if (!server->disconnected)
|
||||
|
|
@ -510,5 +518,131 @@ dbus_server_get_n_connections (DBusServer *server)
|
|||
return _dbus_counter_get_value (server->connection_counter);
|
||||
}
|
||||
|
||||
|
||||
static DBusDataSlotAllocator slot_allocator;
|
||||
|
||||
/**
|
||||
* Initialize the mutex used for #DBusConnection data
|
||||
* slot reservations.
|
||||
*
|
||||
* @returns the mutex
|
||||
*/
|
||||
DBusMutex *
|
||||
_dbus_server_slots_init_lock (void)
|
||||
{
|
||||
if (!_dbus_data_slot_allocator_init (&slot_allocator))
|
||||
return NULL;
|
||||
else
|
||||
return slot_allocator.lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates an integer ID to be used for storing application-specific
|
||||
* data on any DBusServer. The allocated ID may then be used
|
||||
* with dbus_server_set_data() and dbus_server_get_data().
|
||||
* If allocation fails, -1 is returned. Again, the allocated
|
||||
* slot is global, i.e. all DBusServer objects will
|
||||
* have a slot with the given integer ID reserved.
|
||||
*
|
||||
* @returns -1 on failure, otherwise the data slot ID
|
||||
*/
|
||||
int
|
||||
dbus_server_allocate_data_slot (void)
|
||||
{
|
||||
return _dbus_data_slot_allocator_alloc (&slot_allocator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates a global ID for server data slots.
|
||||
* dbus_server_get_data() and dbus_server_set_data()
|
||||
* may no longer be used with this slot.
|
||||
* Existing data stored on existing DBusServer objects
|
||||
* will be freed when the server 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_server_free_data_slot (int slot)
|
||||
{
|
||||
_dbus_data_slot_allocator_free (&slot_allocator, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a pointer on a DBusServer, along
|
||||
* with an optional function to be used for freeing
|
||||
* the data when the data is set again, or when
|
||||
* the server is finalized. The slot number
|
||||
* must have been allocated with dbus_server_allocate_data_slot().
|
||||
*
|
||||
* @param server the server
|
||||
* @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_server_set_data (DBusServer *server,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func)
|
||||
{
|
||||
DBusFreeFunction old_free_func;
|
||||
void *old_data;
|
||||
dbus_bool_t retval;
|
||||
|
||||
#if 0
|
||||
dbus_mutex_lock (server->mutex);
|
||||
#endif
|
||||
|
||||
retval = _dbus_data_slot_list_set (&slot_allocator,
|
||||
&server->slot_list,
|
||||
slot, data, free_data_func,
|
||||
&old_free_func, &old_data);
|
||||
|
||||
#if 0
|
||||
dbus_mutex_unlock (server->mutex);
|
||||
#endif
|
||||
|
||||
if (retval)
|
||||
{
|
||||
/* Do the actual free outside the server lock */
|
||||
if (old_free_func)
|
||||
(* old_free_func) (old_data);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data previously set with dbus_server_set_data().
|
||||
* The slot must still be allocated (must not have been freed).
|
||||
*
|
||||
* @param server the server
|
||||
* @param slot the slot to get data from
|
||||
* @returns the data, or #NULL if not found
|
||||
*/
|
||||
void*
|
||||
dbus_server_get_data (DBusServer *server,
|
||||
int slot)
|
||||
{
|
||||
void *res;
|
||||
|
||||
#if 0
|
||||
dbus_mutex_lock (server->mutex);
|
||||
#endif
|
||||
|
||||
res = _dbus_data_slot_list_get (&slot_allocator,
|
||||
&server->slot_list,
|
||||
slot);
|
||||
|
||||
#if 0
|
||||
dbus_mutex_unlock (server->mutex);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,15 @@ 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);
|
||||
dbus_bool_t dbus_server_set_data (DBusServer *server,
|
||||
int slot,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_func);
|
||||
void* dbus_server_get_data (DBusServer *server,
|
||||
int slot);
|
||||
|
||||
DBUS_END_DECLS;
|
||||
|
||||
#endif /* DBUS_SERVER_H */
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir)
|
|||
if (!_dbus_string_test ())
|
||||
die ("strings");
|
||||
|
||||
printf ("%s: running data slot tests\n", "dbus-test");
|
||||
if (!_dbus_data_slot_test ())
|
||||
die ("dataslot");
|
||||
|
||||
printf ("%s: running keyring tests\n", "dbus-test");
|
||||
if (!_dbus_keyring_test ())
|
||||
die ("keyring");
|
||||
|
|
|
|||
|
|
@ -35,17 +35,18 @@ typedef enum
|
|||
_DBUS_MESSAGE_UNKNOWN
|
||||
} DBusMessageValidity;
|
||||
|
||||
dbus_bool_t _dbus_hash_test (void);
|
||||
dbus_bool_t _dbus_list_test (void);
|
||||
dbus_bool_t _dbus_marshal_test (void);
|
||||
dbus_bool_t _dbus_mem_pool_test (void);
|
||||
dbus_bool_t _dbus_string_test (void);
|
||||
dbus_bool_t _dbus_address_test (void);
|
||||
dbus_bool_t _dbus_message_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_auth_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_md5_test (void);
|
||||
dbus_bool_t _dbus_sha_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_keyring_test (void);
|
||||
dbus_bool_t _dbus_hash_test (void);
|
||||
dbus_bool_t _dbus_list_test (void);
|
||||
dbus_bool_t _dbus_marshal_test (void);
|
||||
dbus_bool_t _dbus_mem_pool_test (void);
|
||||
dbus_bool_t _dbus_string_test (void);
|
||||
dbus_bool_t _dbus_address_test (void);
|
||||
dbus_bool_t _dbus_message_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_auth_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_md5_test (void);
|
||||
dbus_bool_t _dbus_sha_test (const char *test_data_dir);
|
||||
dbus_bool_t _dbus_keyring_test (void);
|
||||
dbus_bool_t _dbus_data_slot_test (void);
|
||||
|
||||
void dbus_internal_do_not_use_run_tests (const char *test_data_dir);
|
||||
dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename,
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ init_static_locks(void)
|
|||
DBusMutex *mutex;
|
||||
} static_locks[] = {
|
||||
{&_dbus_list_init_lock},
|
||||
{&_dbus_allocated_slots_init_lock},
|
||||
{&_dbus_server_slots_init_lock},
|
||||
{&_dbus_connection_slots_init_lock},
|
||||
{&_dbus_atomic_init_lock},
|
||||
{&_dbus_message_handler_init_lock},
|
||||
{&_dbus_user_info_init_lock}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,12 @@ check_write_watch (DBusTransport *transport)
|
|||
_dbus_watch_unref (unix_transport->write_watch);
|
||||
unix_transport->write_watch = NULL;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Write watch is unchanged from %p on fd %d\n",
|
||||
unix_transport->write_watch, unix_transport->fd);
|
||||
}
|
||||
|
||||
out:
|
||||
_dbus_transport_unref (transport);
|
||||
}
|
||||
|
|
@ -173,9 +178,16 @@ check_read_watch (DBusTransport *transport)
|
|||
|
||||
_dbus_transport_ref (transport);
|
||||
|
||||
need_read_watch =
|
||||
_dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
|
||||
if (_dbus_transport_get_is_authenticated (transport))
|
||||
need_read_watch =
|
||||
_dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
|
||||
else
|
||||
need_read_watch = transport->receive_credentials_pending ||
|
||||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
|
||||
|
||||
_dbus_verbose ("need_read_watch = %d authenticated = %d\n",
|
||||
need_read_watch, _dbus_transport_get_is_authenticated (transport));
|
||||
|
||||
if (transport->disconnected)
|
||||
need_read_watch = FALSE;
|
||||
|
||||
|
|
@ -213,7 +225,12 @@ check_read_watch (DBusTransport *transport)
|
|||
_dbus_watch_unref (unix_transport->read_watch);
|
||||
unix_transport->read_watch = NULL;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Read watch is unchanged from %p on fd %d\n",
|
||||
unix_transport->read_watch, unix_transport->fd);
|
||||
}
|
||||
|
||||
out:
|
||||
_dbus_transport_unref (transport);
|
||||
}
|
||||
|
|
@ -552,6 +569,7 @@ do_authentication (DBusTransport *transport,
|
|||
}
|
||||
|
||||
out:
|
||||
check_read_watch (transport);
|
||||
check_write_watch (transport);
|
||||
_dbus_transport_unref (transport);
|
||||
}
|
||||
|
|
@ -902,10 +920,12 @@ unix_do_iteration (DBusTransport *transport,
|
|||
dbus_bool_t do_select;
|
||||
int select_res;
|
||||
|
||||
_dbus_verbose (" iteration flags = %s%s timeout = %d\n",
|
||||
_dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n",
|
||||
flags & DBUS_ITERATION_DO_READING ? "read" : "",
|
||||
flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
|
||||
timeout_milliseconds);
|
||||
timeout_milliseconds,
|
||||
unix_transport->read_watch,
|
||||
unix_transport->write_watch);
|
||||
|
||||
/* "again" has to be up here because on EINTR the fd sets become
|
||||
* undefined
|
||||
|
|
@ -948,13 +968,15 @@ unix_do_iteration (DBusTransport *transport,
|
|||
|
||||
auth_state = _dbus_auth_do_work (transport->auth);
|
||||
|
||||
if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
|
||||
if (transport->receive_credentials_pending ||
|
||||
auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
|
||||
{
|
||||
FD_SET (unix_transport->fd, &read_set);
|
||||
do_select = TRUE;
|
||||
}
|
||||
|
||||
if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
|
||||
if (transport->send_credentials_pending ||
|
||||
auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
|
||||
{
|
||||
FD_SET (unix_transport->fd, &write_set);
|
||||
do_select = TRUE;
|
||||
|
|
|
|||
|
|
@ -485,6 +485,9 @@ _dbus_transport_do_iteration (DBusTransport *transport,
|
|||
{
|
||||
_dbus_assert (transport->vtable->do_iteration != NULL);
|
||||
|
||||
_dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
|
||||
flags, timeout_milliseconds, !transport->disconnected);
|
||||
|
||||
if ((flags & (DBUS_ITERATION_DO_WRITING |
|
||||
DBUS_ITERATION_DO_READING)) == 0)
|
||||
return; /* Nothing to do */
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
#include <dbus/dbus.h>
|
||||
#include <glib.h>
|
||||
|
||||
void dbus_gthread_init (void);
|
||||
void dbus_connection_hookup_with_g_main (DBusConnection *connection);
|
||||
void dbus_gthread_init (void);
|
||||
void dbus_connection_setup_with_g_main (DBusConnection *connection);
|
||||
void dbus_server_setup_with_g_main (DBusServer *server);
|
||||
|
||||
#endif /* DBUS_GLIB_H */
|
||||
|
|
|
|||
|
|
@ -24,40 +24,77 @@
|
|||
#include "dbus-glib.h"
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct _DBusGSource DBusGSource;
|
||||
/**
|
||||
* @defgroup DBusGLib GLib bindings
|
||||
* @ingroup DBus
|
||||
* @brief API for using D-BUS with GLib
|
||||
*
|
||||
* Convenience functions are provided for using D-BUS
|
||||
* with the GLib library (see http://www.gtk.org for GLib
|
||||
* information).
|
||||
*
|
||||
*/
|
||||
|
||||
struct _DBusGSource
|
||||
/**
|
||||
* @defgroup DBusGLibInternals GLib bindings implementation details
|
||||
* @ingroup DBusInternals
|
||||
* @brief Implementation details of GLib bindings
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @typedef DBusGSource
|
||||
* A GSource representing a #DBusConnection or #DBusServer
|
||||
*/
|
||||
typedef struct DBusGSource DBusGSource;
|
||||
|
||||
struct DBusGSource
|
||||
{
|
||||
GSource source;
|
||||
GSource source; /**< the parent GSource */
|
||||
|
||||
DBusConnection *connection;
|
||||
GList *poll_fds; /**< descriptors we're watching */
|
||||
GHashTable *watches; /**< hash of DBusWatch objects */
|
||||
|
||||
GList *poll_fds;
|
||||
GHashTable *watches;
|
||||
void *connection_or_server; /**< DBusConnection or DBusServer */
|
||||
};
|
||||
|
||||
static GStaticMutex connection_slot_lock = G_STATIC_MUTEX_INIT;
|
||||
static int connection_slot = -1;
|
||||
static GStaticMutex server_slot_lock = G_STATIC_MUTEX_INIT;
|
||||
static int server_slot = -1;
|
||||
|
||||
static gboolean dbus_connection_prepare (GSource *source,
|
||||
gint *timeout);
|
||||
gint *timeout);
|
||||
static gboolean dbus_connection_check (GSource *source);
|
||||
static gboolean dbus_connection_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
static gboolean dbus_server_prepare (GSource *source,
|
||||
gint *timeout);
|
||||
static gboolean dbus_server_check (GSource *source);
|
||||
static gboolean dbus_server_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
static GSourceFuncs dbus_funcs = {
|
||||
static GSourceFuncs dbus_connection_funcs = {
|
||||
dbus_connection_prepare,
|
||||
dbus_connection_check,
|
||||
dbus_connection_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
static GSourceFuncs dbus_server_funcs = {
|
||||
dbus_server_prepare,
|
||||
dbus_server_check,
|
||||
dbus_server_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
static gboolean
|
||||
dbus_connection_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
DBusConnection *connection = ((DBusGSource *)source)->connection;
|
||||
DBusConnection *connection = ((DBusGSource *)source)->connection_or_server;
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
|
|
@ -65,7 +102,16 @@ dbus_connection_prepare (GSource *source,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
dbus_connection_check (GSource *source)
|
||||
dbus_server_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
*timeout = -1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_gsource_check (GSource *source)
|
||||
{
|
||||
DBusGSource *dbus_source = (DBusGSource *)source;
|
||||
GList *list;
|
||||
|
|
@ -86,9 +132,22 @@ dbus_connection_check (GSource *source)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
dbus_connection_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
dbus_connection_check (GSource *source)
|
||||
{
|
||||
return dbus_gsource_check (source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_server_check (GSource *source)
|
||||
{
|
||||
return dbus_gsource_check (source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_gsource_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data,
|
||||
dbus_bool_t is_server)
|
||||
{
|
||||
DBusGSource *dbus_source = (DBusGSource *)source;
|
||||
GList *copy, *list;
|
||||
|
|
@ -115,21 +174,63 @@ dbus_connection_dispatch (GSource *source,
|
|||
condition |= DBUS_WATCH_ERROR;
|
||||
if (poll_fd->revents & G_IO_HUP)
|
||||
condition |= DBUS_WATCH_HANGUP;
|
||||
|
||||
dbus_connection_handle_watch (dbus_source->connection, watch, condition);
|
||||
|
||||
if (is_server)
|
||||
dbus_server_handle_watch (dbus_source->connection_or_server,
|
||||
watch, condition);
|
||||
else
|
||||
dbus_connection_handle_watch (dbus_source->connection_or_server,
|
||||
watch, condition);
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
||||
/* Dispatch messages */
|
||||
while (dbus_connection_dispatch_message (dbus_source->connection));
|
||||
g_list_free (copy);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_connection_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
DBusGSource *dbus_source = (DBusGSource *)source;
|
||||
DBusConnection *connection = dbus_source->connection_or_server;
|
||||
|
||||
dbus_connection_ref (connection);
|
||||
|
||||
dbus_gsource_dispatch (source, callback, user_data,
|
||||
FALSE);
|
||||
|
||||
/* Dispatch messages */
|
||||
while (dbus_connection_dispatch_message (connection))
|
||||
;
|
||||
|
||||
dbus_connection_unref (connection);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_server_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
DBusGSource *dbus_source = (DBusGSource *)source;
|
||||
DBusServer *server = dbus_source->connection_or_server;
|
||||
|
||||
dbus_server_ref (server);
|
||||
|
||||
dbus_gsource_dispatch (source, callback, user_data,
|
||||
TRUE);
|
||||
|
||||
dbus_server_unref (server);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_watch (DBusWatch *watch,
|
||||
gpointer data)
|
||||
|
|
@ -184,7 +285,6 @@ timeout_handler (gpointer data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_timeout (DBusTimeout *timeout,
|
||||
void *data)
|
||||
|
|
@ -204,7 +304,7 @@ remove_timeout (DBusTimeout *timeout,
|
|||
guint timeout_tag;
|
||||
|
||||
timeout_tag = GPOINTER_TO_UINT (dbus_timeout_get_data (timeout));
|
||||
|
||||
|
||||
g_source_remove (timeout_tag);
|
||||
}
|
||||
|
||||
|
|
@ -214,33 +314,112 @@ free_source (GSource *source)
|
|||
g_source_destroy (source);
|
||||
}
|
||||
|
||||
void
|
||||
dbus_connection_hookup_with_g_main (DBusConnection *connection)
|
||||
/** @} */ /* End of GLib bindings internals */
|
||||
|
||||
/** @addtogroup DBusGLib
|
||||
* @{
|
||||
*/
|
||||
|
||||
static GSource*
|
||||
create_source (void *connection_or_server,
|
||||
GSourceFuncs *funcs)
|
||||
{
|
||||
GSource *source;
|
||||
DBusGSource *dbus_source;
|
||||
|
||||
source = g_source_new (&dbus_funcs, sizeof (DBusGSource));
|
||||
source = g_source_new (funcs, sizeof (DBusGSource));
|
||||
|
||||
dbus_source = (DBusGSource *)source;
|
||||
dbus_source->watches = g_hash_table_new (NULL, NULL);
|
||||
dbus_source->connection = connection;
|
||||
dbus_source->connection_or_server = connection_or_server;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the watch and timeout functions of a #DBusConnection
|
||||
* to integrate the connection with the GLib main loop.
|
||||
*
|
||||
* @param connection the connection
|
||||
*/
|
||||
void
|
||||
dbus_connection_setup_with_g_main (DBusConnection *connection)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
source = create_source (connection, &dbus_connection_funcs);
|
||||
|
||||
dbus_connection_set_watch_functions (connection,
|
||||
add_watch,
|
||||
remove_watch,
|
||||
source, NULL);
|
||||
dbus_connection_set_timeout_functions (connection,
|
||||
add_timeout,
|
||||
remove_timeout,
|
||||
NULL, NULL);
|
||||
add_watch,
|
||||
remove_watch,
|
||||
source, NULL);
|
||||
|
||||
dbus_connection_set_timeout_functions (connection,
|
||||
add_timeout,
|
||||
remove_timeout,
|
||||
NULL, NULL);
|
||||
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
g_static_mutex_lock (&connection_slot_lock);
|
||||
if (connection_slot == -1 )
|
||||
connection_slot = dbus_connection_allocate_data_slot ();
|
||||
g_static_mutex_unlock (&connection_slot_lock);
|
||||
|
||||
dbus_connection_set_data (connection, connection_slot, source,
|
||||
(DBusFreeFunction)free_source);
|
||||
|
||||
if (connection_slot < 0)
|
||||
goto nomem;
|
||||
|
||||
if (!dbus_connection_set_data (connection, connection_slot, source,
|
||||
(DBusFreeFunction)free_source))
|
||||
goto nomem;
|
||||
|
||||
return;
|
||||
|
||||
nomem:
|
||||
g_error ("Not enough memory to set up DBusConnection for use with GLib");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the watch and timeout functions of a #DBusServer
|
||||
* to integrate the server with the GLib main loop.
|
||||
*
|
||||
* @param server the server
|
||||
*/
|
||||
void
|
||||
dbus_server_setup_with_g_main (DBusServer *server)
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
source = create_source (server, &dbus_server_funcs);
|
||||
|
||||
dbus_server_set_watch_functions (server,
|
||||
add_watch,
|
||||
remove_watch,
|
||||
source, NULL);
|
||||
|
||||
dbus_server_set_timeout_functions (server,
|
||||
add_timeout,
|
||||
remove_timeout,
|
||||
NULL, NULL);
|
||||
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
g_static_mutex_lock (&server_slot_lock);
|
||||
if (server_slot == -1 )
|
||||
server_slot = dbus_server_allocate_data_slot ();
|
||||
g_static_mutex_unlock (&server_slot_lock);
|
||||
|
||||
if (server_slot < 0)
|
||||
goto nomem;
|
||||
|
||||
if (!dbus_server_set_data (server, server_slot, source,
|
||||
(DBusFreeFunction)free_source))
|
||||
goto nomem;
|
||||
|
||||
return;
|
||||
|
||||
nomem:
|
||||
g_error ("Not enough memory to set up DBusServer for use with GLib");
|
||||
}
|
||||
|
||||
/** @} */ /* end of public API */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@
|
|||
#include <dbus/dbus.h>
|
||||
#include "dbus-glib.h"
|
||||
|
||||
/** @addtogroup DBusGLibInternals
|
||||
* @{
|
||||
*/
|
||||
|
||||
static DBusMutex * dbus_gmutex_new (void);
|
||||
static void dbus_gmutex_free (DBusMutex *mutex);
|
||||
static dbus_bool_t dbus_gmutex_lock (DBusMutex *mutex);
|
||||
|
|
@ -149,7 +153,17 @@ dbus_gcondvar_wake_all (DBusCondVar *cond)
|
|||
g_cond_broadcast ((GCond *)cond);
|
||||
}
|
||||
|
||||
/** @} End of internals */
|
||||
|
||||
/** @addtogroup DBusGLib
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Initializes the D-BUS thread system to use
|
||||
* GLib threads. This function may only be called
|
||||
* once and must be called prior to calling any
|
||||
* other function in the D-BUS API.
|
||||
*/
|
||||
void
|
||||
dbus_gthread_init (void)
|
||||
{
|
||||
|
|
@ -158,3 +172,5 @@ dbus_gthread_init (void)
|
|||
|
||||
dbus_threads_init (&functions);
|
||||
}
|
||||
|
||||
/** @} end of public API */
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ main (int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
dbus_connection_hookup_with_g_main (connection);
|
||||
dbus_connection_setup_with_g_main (connection);
|
||||
|
||||
message = dbus_message_new ("org.freedesktop.DBus", "org.freedesktop.DBus.Hello");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue