mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-02-18 02:30:31 +01:00
2003-03-12 Havoc Pennington <hp@pobox.com>
Throughout: purge global variables, introduce BusActivation, BusConnections, BusRegistry, etc. objects instead. * bus/bus.h, bus/bus.c: introduce BusContext as a global message bus object * test/Makefile.am (TEST_BINARIES): disable bus-test for now, going to redo this a bit differently I think
This commit is contained in:
parent
29560adcc7
commit
6ecc14ffab
14 changed files with 742 additions and 327 deletions
11
ChangeLog
11
ChangeLog
|
|
@ -1,3 +1,14 @@
|
|||
2003-03-12 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
Throughout: purge global variables, introduce BusActivation,
|
||||
BusConnections, BusRegistry, etc. objects instead.
|
||||
|
||||
* bus/bus.h, bus/bus.c: introduce BusContext as a global
|
||||
message bus object
|
||||
|
||||
* test/Makefile.am (TEST_BINARIES): disable bus-test for now,
|
||||
going to redo this a bit differently I think
|
||||
|
||||
2003-03-12 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
Mega-patch that gets the message bus daemon initially handling
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ noinst_LTLIBRARIES=libdbus-daemon.la
|
|||
libdbus_daemon_la_SOURCES= \
|
||||
activation.c \
|
||||
activation.h \
|
||||
bus.c \
|
||||
bus.h \
|
||||
connection.c \
|
||||
connection.h \
|
||||
desktop-file.c \
|
||||
|
|
|
|||
101
bus/activation.c
101
bus/activation.c
|
|
@ -33,8 +33,12 @@
|
|||
#define DBUS_SERVICE_NAME "Name"
|
||||
#define DBUS_SERVICE_EXEC "Exec"
|
||||
|
||||
static DBusHashTable *activation_entries = NULL;
|
||||
static char *server_address = NULL;
|
||||
struct BusActivation
|
||||
{
|
||||
int refcount;
|
||||
DBusHashTable *entries;
|
||||
char *server_address;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -42,12 +46,6 @@ typedef struct
|
|||
char *exec;
|
||||
} BusActivationEntry;
|
||||
|
||||
static DBusHashTable *pending_activations = NULL;
|
||||
typedef struct
|
||||
{
|
||||
char *service;
|
||||
} BusPendingActivation;
|
||||
|
||||
static void
|
||||
bus_activation_entry_free (BusActivationEntry *entry)
|
||||
{
|
||||
|
|
@ -59,7 +57,8 @@ bus_activation_entry_free (BusActivationEntry *entry)
|
|||
}
|
||||
|
||||
static dbus_bool_t
|
||||
add_desktop_file_entry (BusDesktopFile *desktop_file,
|
||||
add_desktop_file_entry (BusActivation *activation,
|
||||
BusDesktopFile *desktop_file,
|
||||
DBusError *error)
|
||||
{
|
||||
char *name, *exec;
|
||||
|
|
@ -92,7 +91,7 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
|
|||
/* FIXME we need a better-defined algorithm for which service file to
|
||||
* pick than "whichever one is first in the directory listing"
|
||||
*/
|
||||
if (_dbus_hash_table_lookup_string (activation_entries, name))
|
||||
if (_dbus_hash_table_lookup_string (activation->entries, name))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Service %s already exists in activation entry list\n", name);
|
||||
|
|
@ -109,7 +108,7 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
|
|||
entry->name = name;
|
||||
entry->exec = exec;
|
||||
|
||||
if (!_dbus_hash_table_insert_string (activation_entries, entry->name, entry))
|
||||
if (!_dbus_hash_table_insert_string (activation->entries, entry->name, entry))
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
|
|
@ -131,8 +130,9 @@ add_desktop_file_entry (BusDesktopFile *desktop_file,
|
|||
* hash entries it already added.
|
||||
*/
|
||||
static dbus_bool_t
|
||||
load_directory (const char *directory,
|
||||
DBusError *error)
|
||||
load_directory (BusActivation *activation,
|
||||
const char *directory,
|
||||
DBusError *error)
|
||||
{
|
||||
DBusDirIter *iter;
|
||||
DBusString dir, filename;
|
||||
|
|
@ -213,7 +213,7 @@ load_directory (const char *directory,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!add_desktop_file_entry (desktop_file, &tmp_error))
|
||||
if (!add_desktop_file_entry (activation, desktop_file, &tmp_error))
|
||||
{
|
||||
const char *full_path_c;
|
||||
|
||||
|
|
@ -263,27 +263,34 @@ load_directory (const char *directory,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_activation_init (const char *address,
|
||||
const char **directories,
|
||||
DBusError *error)
|
||||
BusActivation*
|
||||
bus_activation_new (const char *address,
|
||||
const char **directories,
|
||||
DBusError *error)
|
||||
{
|
||||
int i;
|
||||
BusActivation *activation;
|
||||
|
||||
_dbus_assert (server_address == NULL);
|
||||
_dbus_assert (activation_entries == NULL);
|
||||
activation = dbus_new0 (BusActivation, 1);
|
||||
if (activation == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
activation->refcount = 1;
|
||||
|
||||
/* FIXME: We should split up the server addresses. */
|
||||
server_address = _dbus_strdup (address);
|
||||
if (server_address == NULL)
|
||||
activation->server_address = _dbus_strdup (address);
|
||||
if (activation->server_address == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
activation_entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
|
||||
activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
|
||||
(DBusFreeFunction)bus_activation_entry_free);
|
||||
if (activation_entries == NULL)
|
||||
if (activation->entries == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
|
|
@ -293,39 +300,63 @@ bus_activation_init (const char *address,
|
|||
i = 0;
|
||||
while (directories[i] != NULL)
|
||||
{
|
||||
if (!load_directory (directories[i], error))
|
||||
if (!load_directory (activation, directories[i], error))
|
||||
goto failed;
|
||||
++i;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return activation;
|
||||
|
||||
failed:
|
||||
dbus_free (server_address);
|
||||
if (activation_entries)
|
||||
_dbus_hash_table_unref (activation_entries);
|
||||
bus_activation_unref (activation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bus_activation_ref (BusActivation *activation)
|
||||
{
|
||||
_dbus_assert (activation->refcount > 0);
|
||||
|
||||
return FALSE;
|
||||
activation->refcount += 1;
|
||||
}
|
||||
|
||||
void
|
||||
bus_activation_unref (BusActivation *activation)
|
||||
{
|
||||
_dbus_assert (activation->refcount > 0);
|
||||
|
||||
activation->refcount -= 1;
|
||||
|
||||
if (activation->refcount == 0)
|
||||
{
|
||||
dbus_free (activation->server_address);
|
||||
if (activation->entries)
|
||||
_dbus_hash_table_unref (activation->entries);
|
||||
dbus_free (activation);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
child_setup (void *data)
|
||||
{
|
||||
BusActivation *activation = data;
|
||||
|
||||
/* If no memory, we simply have the child exit, so it won't try
|
||||
* to connect to the wrong thing.
|
||||
*/
|
||||
if (!_dbus_setenv ("DBUS_ADDRESS", server_address))
|
||||
if (!_dbus_setenv ("DBUS_ADDRESS", activation->server_address))
|
||||
_dbus_exit (1);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_activation_activate_service (const char *service_name,
|
||||
DBusError *error)
|
||||
bus_activation_activate_service (BusActivation *activation,
|
||||
const char *service_name,
|
||||
DBusError *error)
|
||||
{
|
||||
BusActivationEntry *entry;
|
||||
char *argv[2];
|
||||
|
||||
entry = _dbus_hash_table_lookup_string (activation_entries, service_name);
|
||||
entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
|
|
@ -344,7 +375,7 @@ bus_activation_activate_service (const char *service_name,
|
|||
argv[1] = NULL;
|
||||
|
||||
if (!_dbus_spawn_async (argv,
|
||||
child_setup, NULL,
|
||||
child_setup, activation,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,17 @@
|
|||
#define BUS_ACTIVATION_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include "bus.h"
|
||||
|
||||
BusActivation* bus_activation_new (const char *address,
|
||||
const char **paths,
|
||||
DBusError *error);
|
||||
void bus_activation_ref (BusActivation *activation);
|
||||
void bus_activation_unref (BusActivation *activation);
|
||||
dbus_bool_t bus_activation_activate_service (BusActivation *activation,
|
||||
const char *service_name,
|
||||
DBusError *error);
|
||||
|
||||
dbus_bool_t bus_activation_init (const char *address,
|
||||
const char **paths,
|
||||
DBusError *error);
|
||||
dbus_bool_t bus_activation_activate_service (const char *service_name,
|
||||
DBusError *error);
|
||||
|
||||
|
||||
#endif /* BUS_ACTIVATION_H */
|
||||
|
|
|
|||
202
bus/bus.c
Normal file
202
bus/bus.c
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* bus.c message bus context object
|
||||
*
|
||||
* 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 "bus.h"
|
||||
#include "loop.h"
|
||||
#include "activation.h"
|
||||
#include "connection.h"
|
||||
#include "services.h"
|
||||
#include "utils.h"
|
||||
#include <dbus/dbus-internals.h>
|
||||
|
||||
struct BusContext
|
||||
{
|
||||
int refcount;
|
||||
char *address;
|
||||
DBusServer *server;
|
||||
BusConnections *connections;
|
||||
BusActivation *activation;
|
||||
BusRegistry *registry;
|
||||
};
|
||||
|
||||
static void
|
||||
server_watch_callback (DBusWatch *watch,
|
||||
unsigned int condition,
|
||||
void *data)
|
||||
{
|
||||
BusContext *context = data;
|
||||
|
||||
dbus_server_handle_watch (context->server, watch, condition);
|
||||
}
|
||||
|
||||
static void
|
||||
add_server_watch (DBusWatch *watch,
|
||||
BusContext *context)
|
||||
{
|
||||
bus_loop_add_watch (watch, server_watch_callback, context,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_server_watch (DBusWatch *watch,
|
||||
BusContext *context)
|
||||
{
|
||||
bus_loop_remove_watch (watch, server_watch_callback, context);
|
||||
}
|
||||
|
||||
static void
|
||||
new_connection_callback (DBusServer *server,
|
||||
DBusConnection *new_connection,
|
||||
void *data)
|
||||
{
|
||||
BusContext *context = data;
|
||||
|
||||
if (!bus_connections_setup_connection (context->connections, new_connection))
|
||||
_dbus_verbose ("No memory to setup new connection\n");
|
||||
|
||||
/* on OOM, we won't have ref'd the connection so it will die */
|
||||
}
|
||||
|
||||
BusContext*
|
||||
bus_context_new (const char *address,
|
||||
const char **service_dirs,
|
||||
DBusError *error)
|
||||
{
|
||||
BusContext *context;
|
||||
DBusResultCode result;
|
||||
|
||||
context = dbus_new0 (BusContext, 1);
|
||||
if (context == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->refcount = 1;
|
||||
|
||||
context->address = _dbus_strdup (address);
|
||||
if (context->address == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
context->server = dbus_server_listen (address, &result);
|
||||
if (context->server == NULL)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"Failed to start server on %s: %s\n",
|
||||
address, dbus_result_to_string (result));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
context->activation = bus_activation_new (address, service_dirs,
|
||||
error);
|
||||
if (context->activation == NULL)
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
context->connections = bus_connections_new (context);
|
||||
if (context->connections == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
context->registry = bus_registry_new ();
|
||||
if (context->registry == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dbus_server_set_new_connection_function (context->server,
|
||||
new_connection_callback,
|
||||
context, NULL);
|
||||
|
||||
dbus_server_set_watch_functions (context->server,
|
||||
(DBusAddWatchFunction) add_server_watch,
|
||||
(DBusRemoveWatchFunction) remove_server_watch,
|
||||
context,
|
||||
NULL);
|
||||
|
||||
return context;
|
||||
|
||||
failed:
|
||||
bus_context_unref (context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bus_context_shutdown (BusContext *context)
|
||||
{
|
||||
dbus_server_disconnect (context->server);
|
||||
}
|
||||
|
||||
void
|
||||
bus_context_ref (BusContext *context)
|
||||
{
|
||||
_dbus_assert (context->refcount > 0);
|
||||
context->refcount += 1;
|
||||
}
|
||||
|
||||
void
|
||||
bus_context_unref (BusContext *context)
|
||||
{
|
||||
_dbus_assert (context->refcount > 0);
|
||||
context->refcount -= 1;
|
||||
|
||||
if (context->refcount == 0)
|
||||
{
|
||||
if (context->registry)
|
||||
bus_registry_unref (context->registry);
|
||||
if (context->connections)
|
||||
bus_connections_unref (context->connections);
|
||||
if (context->activation)
|
||||
bus_activation_unref (context->activation);
|
||||
if (context->server)
|
||||
dbus_server_unref (context->server);
|
||||
dbus_free (context->address);
|
||||
dbus_free (context);
|
||||
}
|
||||
}
|
||||
|
||||
BusRegistry*
|
||||
bus_context_get_registry (BusContext *context)
|
||||
{
|
||||
return context->registry;
|
||||
}
|
||||
|
||||
BusConnections*
|
||||
bus_context_get_connections (BusContext *context)
|
||||
{
|
||||
return context->connections;
|
||||
}
|
||||
|
||||
BusActivation*
|
||||
bus_context_get_activation (BusContext *context)
|
||||
{
|
||||
return context->activation;
|
||||
}
|
||||
48
bus/bus.h
Normal file
48
bus/bus.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* bus.h message bus context object
|
||||
*
|
||||
* 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_BUS_H
|
||||
#define BUS_BUS_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-string.h>
|
||||
|
||||
typedef struct BusActivation BusActivation;
|
||||
typedef struct BusConnections BusConnections;
|
||||
typedef struct BusContext BusContext;
|
||||
typedef struct BusRegistry BusRegistry;
|
||||
typedef struct BusService BusService;
|
||||
typedef struct BusTransaction BusTransaction;
|
||||
|
||||
BusContext* bus_context_new (const char *address,
|
||||
const char **service_dirs,
|
||||
DBusError *error);
|
||||
void bus_context_shutdown (BusContext *context);
|
||||
void bus_context_ref (BusContext *context);
|
||||
void bus_context_unref (BusContext *context);
|
||||
BusRegistry* bus_context_get_registry (BusContext *context);
|
||||
BusConnections* bus_context_get_connections (BusContext *context);
|
||||
BusActivation* bus_context_get_activation (BusContext *context);
|
||||
|
||||
|
||||
#endif /* BUS_BUS_H */
|
||||
199
bus/connection.c
199
bus/connection.c
|
|
@ -29,11 +29,18 @@
|
|||
|
||||
static void bus_connection_remove_transactions (DBusConnection *connection);
|
||||
|
||||
static int connection_data_slot;
|
||||
static DBusList *connections = NULL;
|
||||
struct BusConnections
|
||||
{
|
||||
int refcount;
|
||||
DBusList *list; /**< List of all the connections */
|
||||
BusContext *context;
|
||||
};
|
||||
|
||||
static int connection_data_slot = -1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BusConnections *connections;
|
||||
DBusConnection *connection;
|
||||
DBusList *services_owned;
|
||||
char *name;
|
||||
|
|
@ -74,7 +81,7 @@ bus_connection_disconnected (DBusConnection *connection)
|
|||
transaction = NULL;
|
||||
while (transaction == NULL)
|
||||
{
|
||||
transaction = bus_transaction_new ();
|
||||
transaction = bus_transaction_new (d->connections->context);
|
||||
bus_wait_for_memory ();
|
||||
}
|
||||
|
||||
|
|
@ -107,12 +114,14 @@ bus_connection_disconnected (DBusConnection *connection)
|
|||
NULL);
|
||||
|
||||
bus_connection_remove_transactions (connection);
|
||||
|
||||
|
||||
_dbus_list_remove (&d->connections->list, connection);
|
||||
|
||||
/* frees "d" as side effect */
|
||||
dbus_connection_set_data (connection,
|
||||
connection_data_slot,
|
||||
NULL, NULL);
|
||||
|
||||
_dbus_list_remove (&connections, connection);
|
||||
|
||||
dbus_connection_unref (connection);
|
||||
}
|
||||
|
||||
|
|
@ -166,19 +175,55 @@ free_connection_data (void *data)
|
|||
dbus_free (d);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_init (void)
|
||||
BusConnections*
|
||||
bus_connections_new (BusContext *context)
|
||||
{
|
||||
connection_data_slot = dbus_connection_allocate_data_slot ();
|
||||
BusConnections *connections;
|
||||
|
||||
if (connection_data_slot < 0)
|
||||
return FALSE;
|
||||
{
|
||||
connection_data_slot = dbus_connection_allocate_data_slot ();
|
||||
|
||||
if (connection_data_slot < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
connections = dbus_new0 (BusConnections, 1);
|
||||
if (connections == NULL)
|
||||
return NULL;
|
||||
|
||||
connections->refcount = 1;
|
||||
connections->context = context;
|
||||
|
||||
return connections;
|
||||
}
|
||||
|
||||
void
|
||||
bus_connections_ref (BusConnections *connections)
|
||||
{
|
||||
_dbus_assert (connections->refcount > 0);
|
||||
connections->refcount += 1;
|
||||
}
|
||||
|
||||
void
|
||||
bus_connections_unref (BusConnections *connections)
|
||||
{
|
||||
_dbus_assert (connections->refcount > 0);
|
||||
connections->refcount -= 1;
|
||||
if (connections->refcount == 0)
|
||||
{
|
||||
/* FIXME free each connection... */
|
||||
_dbus_assert_not_reached ("shutting down connections not implemented");
|
||||
|
||||
_dbus_list_clear (&connections->list);
|
||||
|
||||
dbus_free (connections);
|
||||
}
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_setup (DBusConnection *connection)
|
||||
bus_connections_setup_connection (BusConnections *connections,
|
||||
DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
|
|
@ -187,6 +232,7 @@ bus_connection_setup (DBusConnection *connection)
|
|||
if (d == NULL)
|
||||
return FALSE;
|
||||
|
||||
d->connections = connections;
|
||||
d->connection = connection;
|
||||
|
||||
if (!dbus_connection_set_data (connection,
|
||||
|
|
@ -197,7 +243,7 @@ bus_connection_setup (DBusConnection *connection)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!_dbus_list_append (&connections, connection))
|
||||
if (!_dbus_list_append (&connections->list, connection))
|
||||
{
|
||||
/* this will free our data when connection gets finalized */
|
||||
dbus_connection_disconnect (connection);
|
||||
|
|
@ -219,6 +265,89 @@ bus_connection_setup (DBusConnection *connection)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls function on each connection; if the function returns
|
||||
* #FALSE, stops iterating.
|
||||
*
|
||||
* @param connections the connections object
|
||||
* @param function the function
|
||||
* @param data data to pass to it as a second arg
|
||||
*/
|
||||
void
|
||||
bus_connections_foreach (BusConnections *connections,
|
||||
BusConnectionForeachFunction function,
|
||||
void *data)
|
||||
{
|
||||
DBusList *link;
|
||||
|
||||
link = _dbus_list_get_first_link (&connections->list);
|
||||
while (link != NULL)
|
||||
{
|
||||
DBusConnection *connection = link->data;
|
||||
DBusList *next = _dbus_list_get_next_link (&connections->list, link);
|
||||
|
||||
if (!(* function) (connection, data))
|
||||
break;
|
||||
|
||||
link = next;
|
||||
}
|
||||
}
|
||||
|
||||
BusContext*
|
||||
bus_connections_get_context (BusConnections *connections)
|
||||
{
|
||||
return connections->context;
|
||||
}
|
||||
|
||||
BusContext*
|
||||
bus_connection_get_context (DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
return d->connections->context;
|
||||
}
|
||||
|
||||
BusConnections*
|
||||
bus_connection_get_connections (DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
return d->connections;
|
||||
}
|
||||
|
||||
BusRegistry*
|
||||
bus_connection_get_registry (DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
return bus_context_get_registry (d->connections->context);
|
||||
}
|
||||
|
||||
BusActivation*
|
||||
bus_connection_get_activation (DBusConnection *connection)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
d = BUS_CONNECTION_DATA (connection);
|
||||
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
return bus_context_get_activation (d->connections->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the connection is registered with the message bus.
|
||||
*
|
||||
|
|
@ -361,32 +490,6 @@ bus_connection_get_name (DBusConnection *connection)
|
|||
return d->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls function on each connection; if the function returns
|
||||
* #FALSE, stops iterating.
|
||||
*
|
||||
* @param function the function
|
||||
* @param data data to pass to it as a second arg
|
||||
*/
|
||||
void
|
||||
bus_connection_foreach (BusConnectionForeachFunction function,
|
||||
void *data)
|
||||
{
|
||||
DBusList *link;
|
||||
|
||||
link = _dbus_list_get_first_link (&connections);
|
||||
while (link != NULL)
|
||||
{
|
||||
DBusConnection *connection = link->data;
|
||||
DBusList *next = _dbus_list_get_next_link (&connections, link);
|
||||
|
||||
if (!(* function) (connection, data))
|
||||
break;
|
||||
|
||||
link = next;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BusTransaction *transaction;
|
||||
|
|
@ -397,7 +500,7 @@ typedef struct
|
|||
struct BusTransaction
|
||||
{
|
||||
DBusList *connections;
|
||||
|
||||
BusContext *context;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -414,7 +517,7 @@ message_to_send_free (DBusConnection *connection,
|
|||
}
|
||||
|
||||
BusTransaction*
|
||||
bus_transaction_new (void)
|
||||
bus_transaction_new (BusContext *context)
|
||||
{
|
||||
BusTransaction *transaction;
|
||||
|
||||
|
|
@ -422,9 +525,23 @@ bus_transaction_new (void)
|
|||
if (transaction == NULL)
|
||||
return NULL;
|
||||
|
||||
transaction->context = context;
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
BusContext*
|
||||
bus_transaction_get_context (BusTransaction *transaction)
|
||||
{
|
||||
return transaction->context;
|
||||
}
|
||||
|
||||
BusConnections*
|
||||
bus_transaction_get_connections (BusTransaction *transaction)
|
||||
{
|
||||
return bus_context_get_connections (transaction->context);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_transaction_send_message (BusTransaction *transaction,
|
||||
DBusConnection *connection,
|
||||
|
|
|
|||
|
|
@ -25,14 +25,26 @@
|
|||
#define BUS_CONNECTION_H
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include "services.h"
|
||||
#include "bus.h"
|
||||
|
||||
typedef dbus_bool_t (* BusConnectionForeachFunction) (DBusConnection *connection,
|
||||
void *data);
|
||||
|
||||
dbus_bool_t bus_connection_init (void);
|
||||
|
||||
dbus_bool_t bus_connection_setup (DBusConnection *connection);
|
||||
BusConnections* bus_connections_new (BusContext *context);
|
||||
void bus_connections_ref (BusConnections *connections);
|
||||
void bus_connections_unref (BusConnections *connections);
|
||||
dbus_bool_t bus_connections_setup_connection (BusConnections *connections,
|
||||
DBusConnection *connection);
|
||||
void bus_connections_foreach (BusConnections *connections,
|
||||
BusConnectionForeachFunction function,
|
||||
void *data);
|
||||
BusContext* bus_connections_get_context (BusConnections *connections);
|
||||
|
||||
BusContext* bus_connection_get_context (DBusConnection *connection);
|
||||
BusConnections* bus_connection_get_connections (DBusConnection *connection);
|
||||
BusRegistry* bus_connection_get_registry (DBusConnection *connection);
|
||||
BusActivation* bus_connection_get_activation (DBusConnection *connection);
|
||||
|
||||
dbus_bool_t bus_connection_is_active (DBusConnection *connection);
|
||||
|
||||
|
|
@ -50,14 +62,14 @@ void bus_connection_remove_owned_service (DBusConnection *connection,
|
|||
dbus_bool_t bus_connection_set_name (DBusConnection *connection,
|
||||
const DBusString *name);
|
||||
const char *bus_connection_get_name (DBusConnection *connection);
|
||||
void bus_connection_foreach (BusConnectionForeachFunction function,
|
||||
void *data);
|
||||
|
||||
/* called by dispatch.c when the connection is dropped */
|
||||
void bus_connection_disconnected (DBusConnection *connection);
|
||||
|
||||
/* transaction API so we can send or not send a block of messages as a whole */
|
||||
BusTransaction* bus_transaction_new (void);
|
||||
BusTransaction* bus_transaction_new (BusContext *context);
|
||||
BusContext* bus_transaction_get_context (BusTransaction *transaction);
|
||||
BusConnections* bus_transaction_get_connections (BusTransaction *transaction);
|
||||
dbus_bool_t bus_transaction_send_message (BusTransaction *transaction,
|
||||
DBusConnection *connection,
|
||||
DBusMessage *message);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@
|
|||
#include "dispatch.h"
|
||||
#include "connection.h"
|
||||
#include "driver.h"
|
||||
#include "services.h"
|
||||
#include "utils.h"
|
||||
#include "bus.h"
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -63,14 +65,18 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,
|
|||
{
|
||||
DBusError tmp_error;
|
||||
SendMessageData d;
|
||||
BusConnections *connections;
|
||||
|
||||
_dbus_assert (dbus_message_get_sender (message) != NULL);
|
||||
|
||||
connections = bus_transaction_get_connections (transaction);
|
||||
|
||||
dbus_error_init (&tmp_error);
|
||||
d.message = message;
|
||||
d.transaction = transaction;
|
||||
d.error = &tmp_error;
|
||||
bus_connection_foreach (send_one_message, &d);
|
||||
|
||||
bus_connections_foreach (connections, send_one_message, &d);
|
||||
|
||||
if (dbus_error_is_set (&tmp_error))
|
||||
{
|
||||
|
|
@ -145,9 +151,13 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
|
|||
const char *sender, *service_name, *message_name;
|
||||
DBusError error;
|
||||
BusTransaction *transaction;
|
||||
|
||||
BusContext *context;
|
||||
|
||||
transaction = NULL;
|
||||
dbus_error_init (&error);
|
||||
|
||||
context = bus_connection_get_context (connection);
|
||||
_dbus_assert (context != NULL);
|
||||
|
||||
/* If we can't even allocate an OOM error, we just go to sleep
|
||||
* until we can.
|
||||
|
|
@ -181,7 +191,7 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
|
|||
_dbus_assert (service_name != NULL); /* this message is intended for bus routing */
|
||||
|
||||
/* Create our transaction */
|
||||
transaction = bus_transaction_new ();
|
||||
transaction = bus_transaction_new (context);
|
||||
if (transaction == NULL)
|
||||
{
|
||||
BUS_SET_OOM (&error);
|
||||
|
|
@ -224,9 +234,12 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
|
|||
{
|
||||
DBusString service_string;
|
||||
BusService *service;
|
||||
BusRegistry *registry;
|
||||
|
||||
registry = bus_connection_get_registry (connection);
|
||||
|
||||
_dbus_string_init_const (&service_string, service_name);
|
||||
service = bus_service_lookup (&service_string);
|
||||
service = bus_registry_lookup (registry, &service_string);
|
||||
|
||||
if (service == NULL)
|
||||
{
|
||||
|
|
|
|||
39
bus/driver.c
39
bus/driver.c
|
|
@ -199,7 +199,8 @@ bus_driver_send_service_acquired (DBusConnection *connection,
|
|||
}
|
||||
|
||||
static dbus_bool_t
|
||||
create_unique_client_name (DBusString *str)
|
||||
create_unique_client_name (BusRegistry *registry,
|
||||
DBusString *str)
|
||||
{
|
||||
/* We never want to use the same unique client name twice, because
|
||||
* we want to guarantee that if you send a message to a given unique
|
||||
|
|
@ -246,7 +247,7 @@ create_unique_client_name (DBusString *str)
|
|||
next_minor_number += 1;
|
||||
|
||||
/* Check if a client with the name exists */
|
||||
if (bus_service_lookup (str) == NULL)
|
||||
if (bus_registry_lookup (registry, str) == NULL)
|
||||
break;
|
||||
|
||||
/* drop the number again, try the next one. */
|
||||
|
|
@ -265,6 +266,7 @@ bus_driver_handle_hello (DBusConnection *connection,
|
|||
DBusString unique_name;
|
||||
BusService *service;
|
||||
dbus_bool_t retval;
|
||||
BusRegistry *registry;
|
||||
|
||||
if (!_dbus_string_init (&unique_name, _DBUS_INT_MAX))
|
||||
{
|
||||
|
|
@ -273,8 +275,10 @@ bus_driver_handle_hello (DBusConnection *connection,
|
|||
}
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
registry = bus_connection_get_registry (connection);
|
||||
|
||||
if (!create_unique_client_name (&unique_name))
|
||||
if (!create_unique_client_name (registry, &unique_name))
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
goto out_0;
|
||||
|
|
@ -297,7 +301,8 @@ bus_driver_handle_hello (DBusConnection *connection,
|
|||
goto out_0;
|
||||
|
||||
/* Create the service */
|
||||
service = bus_service_ensure (&unique_name, connection, transaction, error);
|
||||
service = bus_registry_ensure (registry,
|
||||
&unique_name, connection, transaction, error);
|
||||
if (service == NULL)
|
||||
goto out_0;
|
||||
|
||||
|
|
@ -367,7 +372,10 @@ bus_driver_handle_list_services (DBusConnection *connection,
|
|||
DBusMessage *reply;
|
||||
int len;
|
||||
char **services;
|
||||
|
||||
BusRegistry *registry;
|
||||
|
||||
registry = bus_connection_get_registry (connection);
|
||||
|
||||
reply = dbus_message_new_reply (message);
|
||||
if (reply == NULL)
|
||||
{
|
||||
|
|
@ -375,8 +383,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
services = bus_services_list (&len);
|
||||
if (services == NULL)
|
||||
if (!bus_registry_list_services (registry, &services, &len))
|
||||
{
|
||||
dbus_message_unref (reply);
|
||||
BUS_SET_OOM (error);
|
||||
|
|
@ -423,6 +430,9 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
|
|||
dbus_bool_t retval;
|
||||
DBusConnection *old_owner;
|
||||
DBusConnection *current_owner;
|
||||
BusRegistry *registry;
|
||||
|
||||
registry = bus_connection_get_registry (connection);
|
||||
|
||||
if (!dbus_message_get_args (message,
|
||||
error,
|
||||
|
|
@ -438,7 +448,7 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
|
|||
|
||||
_dbus_string_init_const (&service_name, name);
|
||||
|
||||
service = bus_service_lookup (&service_name);
|
||||
service = bus_registry_lookup (registry, &service_name);
|
||||
|
||||
if (service != NULL)
|
||||
old_owner = bus_service_get_primary_owner (service);
|
||||
|
|
@ -454,7 +464,8 @@ bus_driver_handle_acquire_service (DBusConnection *connection,
|
|||
|
||||
if (service == NULL)
|
||||
{
|
||||
service = bus_service_ensure (&service_name, connection, transaction, error);
|
||||
service = bus_registry_ensure (registry,
|
||||
&service_name, connection, transaction, error);
|
||||
if (service == NULL)
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -542,6 +553,9 @@ bus_driver_handle_service_exists (DBusConnection *connection,
|
|||
BusService *service;
|
||||
char *name;
|
||||
dbus_bool_t retval;
|
||||
BusRegistry *registry;
|
||||
|
||||
registry = bus_connection_get_registry (connection);
|
||||
|
||||
if (!dbus_message_get_args (message, error,
|
||||
DBUS_TYPE_STRING, &name,
|
||||
|
|
@ -551,7 +565,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,
|
|||
retval = FALSE;
|
||||
|
||||
_dbus_string_init_const (&service_name, name);
|
||||
service = bus_service_lookup (&service_name);
|
||||
service = bus_registry_lookup (registry, &service_name);
|
||||
|
||||
reply = dbus_message_new_reply (message);
|
||||
if (reply == NULL)
|
||||
|
|
@ -599,6 +613,9 @@ bus_driver_handle_activate_service (DBusConnection *connection,
|
|||
dbus_uint32_t flags;
|
||||
char *name;
|
||||
dbus_bool_t retval;
|
||||
BusActivation *activation;
|
||||
|
||||
activation = bus_connection_get_activation (connection);
|
||||
|
||||
if (!dbus_message_get_args (message, error,
|
||||
DBUS_TYPE_STRING, &name,
|
||||
|
|
@ -608,7 +625,7 @@ bus_driver_handle_activate_service (DBusConnection *connection,
|
|||
|
||||
retval = FALSE;
|
||||
|
||||
if (!bus_activation_activate_service (name, error))
|
||||
if (!bus_activation_activate_service (activation, name, error))
|
||||
goto out;
|
||||
|
||||
retval = TRUE;
|
||||
|
|
|
|||
109
bus/main.c
109
bus/main.c
|
|
@ -20,110 +20,41 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include "bus.h"
|
||||
#include "loop.h"
|
||||
#include "activation.h"
|
||||
#include "connection.h"
|
||||
#include "driver.h"
|
||||
#include <dbus/dbus-list.h>
|
||||
|
||||
static void
|
||||
server_watch_callback (DBusWatch *watch,
|
||||
unsigned int condition,
|
||||
void *data)
|
||||
{
|
||||
DBusServer *server = data;
|
||||
|
||||
dbus_server_handle_watch (server, watch, condition);
|
||||
}
|
||||
|
||||
static void
|
||||
add_server_watch (DBusWatch *watch,
|
||||
DBusServer *server)
|
||||
{
|
||||
bus_loop_add_watch (watch, server_watch_callback, server,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_server_watch (DBusWatch *watch,
|
||||
DBusServer *server)
|
||||
{
|
||||
bus_loop_remove_watch (watch, server_watch_callback, server);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_server (DBusServer *server)
|
||||
{
|
||||
dbus_server_set_watch_functions (server,
|
||||
(DBusAddWatchFunction) add_server_watch,
|
||||
(DBusRemoveWatchFunction) remove_server_watch,
|
||||
server,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
new_connection_callback (DBusServer *server,
|
||||
DBusConnection *new_connection,
|
||||
void *data)
|
||||
{
|
||||
if (!bus_connection_setup (new_connection))
|
||||
; /* we won't have ref'd the connection so it will die */
|
||||
}
|
||||
#include <dbus/dbus-internals.h>
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
DBusServer *server;
|
||||
DBusResultCode result;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
_dbus_warn ("Give the server address as an argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
BusContext *context;
|
||||
DBusError error;
|
||||
const char *paths[] = { NULL, NULL };
|
||||
|
||||
server = dbus_server_listen (argv[1], &result);
|
||||
if (server == NULL)
|
||||
{
|
||||
_dbus_warn ("Failed to start server on %s: %s\n",
|
||||
argv[1], dbus_result_to_string (result));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
_dbus_warn ("No service location given, not activating activation\n");
|
||||
/* FIXME obviously just for testing */
|
||||
_dbus_warn ("Give the server address as an argument and activation directory as args\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
||||
paths[0] = argv[2];
|
||||
|
||||
dbus_error_init (&error);
|
||||
context = bus_context_new (argv[1], paths, &error);
|
||||
if (context == NULL)
|
||||
{
|
||||
const char *paths[] = { argv[2], NULL };
|
||||
DBusError error;
|
||||
|
||||
dbus_error_init (&error);
|
||||
if (!bus_activation_init (argv[1], paths,
|
||||
&error))
|
||||
{
|
||||
_dbus_warn ("Could not initialize service activation: %s\n",
|
||||
error.message);
|
||||
dbus_error_free (&error);
|
||||
return 1;
|
||||
}
|
||||
_dbus_warn ("Failed to start message bus: %s\n",
|
||||
error.message);
|
||||
dbus_error_free (&error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
setup_server (server);
|
||||
|
||||
bus_connection_init ();
|
||||
|
||||
dbus_server_set_new_connection_function (server,
|
||||
new_connection_callback,
|
||||
NULL, NULL);
|
||||
|
||||
_dbus_verbose ("We are on D-Bus...\n");
|
||||
bus_loop_run ();
|
||||
|
||||
dbus_server_disconnect (server);
|
||||
dbus_server_unref (server);
|
||||
bus_context_shutdown (context);
|
||||
bus_context_unref (context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
241
bus/services.c
241
bus/services.c
|
|
@ -32,65 +32,94 @@
|
|||
|
||||
struct BusService
|
||||
{
|
||||
BusRegistry *registry;
|
||||
char *name;
|
||||
DBusList *owners;
|
||||
|
||||
unsigned int prohibit_replacement : 1;
|
||||
};
|
||||
|
||||
static DBusHashTable *service_hash = NULL;
|
||||
static DBusMemPool *service_pool = NULL;
|
||||
|
||||
static dbus_bool_t
|
||||
init_hash (void)
|
||||
struct BusRegistry
|
||||
{
|
||||
if (service_hash == NULL)
|
||||
{
|
||||
service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
NULL, NULL);
|
||||
service_pool = _dbus_mem_pool_new (sizeof (BusService),
|
||||
TRUE);
|
||||
int refcount;
|
||||
|
||||
DBusHashTable *service_hash;
|
||||
DBusMemPool *service_pool;
|
||||
};
|
||||
|
||||
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 FALSE;
|
||||
}
|
||||
BusRegistry*
|
||||
bus_registry_new (void)
|
||||
{
|
||||
BusRegistry *registry;
|
||||
|
||||
registry = dbus_new0 (BusRegistry, 1);
|
||||
if (registry == NULL)
|
||||
return NULL;
|
||||
|
||||
registry->refcount = 1;
|
||||
|
||||
registry->service_hash = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||
NULL, NULL);
|
||||
if (registry->service_hash == NULL)
|
||||
goto failed;
|
||||
|
||||
registry->service_pool = _dbus_mem_pool_new (sizeof (BusService),
|
||||
TRUE);
|
||||
if (registry->service_pool == NULL)
|
||||
goto failed;
|
||||
|
||||
return registry;
|
||||
|
||||
failed:
|
||||
bus_registry_unref (registry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bus_registry_ref (BusRegistry *registry)
|
||||
{
|
||||
_dbus_assert (registry->refcount > 0);
|
||||
registry->refcount += 1;
|
||||
}
|
||||
|
||||
void
|
||||
bus_registry_unref (BusRegistry *registry)
|
||||
{
|
||||
_dbus_assert (registry->refcount > 0);
|
||||
registry->refcount -= 1;
|
||||
|
||||
if (registry->refcount == 0)
|
||||
{
|
||||
if (registry->service_hash)
|
||||
_dbus_hash_table_unref (registry->service_hash);
|
||||
if (registry->service_pool)
|
||||
_dbus_mem_pool_free (registry->service_pool);
|
||||
|
||||
dbus_free (registry);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BusService*
|
||||
bus_service_lookup (const DBusString *service_name)
|
||||
bus_registry_lookup (BusRegistry *registry,
|
||||
const DBusString *service_name)
|
||||
{
|
||||
const char *c_name;
|
||||
BusService *service;
|
||||
|
||||
if (!init_hash ())
|
||||
return NULL;
|
||||
|
||||
_dbus_string_get_const_data (service_name, &c_name);
|
||||
|
||||
service = _dbus_hash_table_lookup_string (service_hash,
|
||||
service = _dbus_hash_table_lookup_string (registry->service_hash,
|
||||
c_name);
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
BusService*
|
||||
bus_service_ensure (const DBusString *service_name,
|
||||
DBusConnection *owner_if_created,
|
||||
BusTransaction *transaction,
|
||||
DBusError *error)
|
||||
bus_registry_ensure (BusRegistry *registry,
|
||||
const DBusString *service_name,
|
||||
DBusConnection *owner_if_created,
|
||||
BusTransaction *transaction,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *c_name;
|
||||
BusService *service;
|
||||
|
|
@ -98,27 +127,26 @@ bus_service_ensure (const DBusString *service_name,
|
|||
_dbus_assert (owner_if_created != NULL);
|
||||
_dbus_assert (transaction != NULL);
|
||||
|
||||
if (!init_hash ())
|
||||
return NULL;
|
||||
|
||||
_dbus_string_get_const_data (service_name, &c_name);
|
||||
|
||||
service = _dbus_hash_table_lookup_string (service_hash,
|
||||
service = _dbus_hash_table_lookup_string (registry->service_hash,
|
||||
c_name);
|
||||
if (service != NULL)
|
||||
return service;
|
||||
|
||||
service = _dbus_mem_pool_alloc (service_pool);
|
||||
service = _dbus_mem_pool_alloc (registry->service_pool);
|
||||
if (service == NULL)
|
||||
{
|
||||
BUS_SET_OOM (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
service->registry = registry;
|
||||
|
||||
service->name = _dbus_strdup (c_name);
|
||||
if (service->name == NULL)
|
||||
{
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
_dbus_mem_pool_dealloc (registry->service_pool, service);
|
||||
BUS_SET_OOM (error);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -126,7 +154,7 @@ bus_service_ensure (const DBusString *service_name,
|
|||
if (!bus_driver_send_service_created (service->name, transaction, error))
|
||||
{
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
_dbus_mem_pool_dealloc (registry->service_pool, service);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -134,17 +162,17 @@ bus_service_ensure (const DBusString *service_name,
|
|||
transaction, error))
|
||||
{
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
_dbus_mem_pool_dealloc (registry->service_pool, service);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dbus_hash_table_insert_string (service_hash,
|
||||
if (!_dbus_hash_table_insert_string (registry->service_hash,
|
||||
service->name,
|
||||
service))
|
||||
{
|
||||
_dbus_list_clear (&service->owners);
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
_dbus_mem_pool_dealloc (registry->service_pool, service);
|
||||
BUS_SET_OOM (error);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -152,6 +180,66 @@ bus_service_ensure (const DBusString *service_name,
|
|||
return service;
|
||||
}
|
||||
|
||||
void
|
||||
bus_registry_foreach (BusRegistry *registry,
|
||||
BusServiceForeachFunction function,
|
||||
void *data)
|
||||
{
|
||||
DBusHashIter iter;
|
||||
|
||||
_dbus_hash_iter_init (registry->service_hash, &iter);
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
BusService *service = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
(* function) (service, data);
|
||||
}
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_registry_list_services (BusRegistry *registry,
|
||||
char ***listp,
|
||||
int *array_len)
|
||||
{
|
||||
int i, j, len;
|
||||
char **retval;
|
||||
DBusHashIter iter;
|
||||
|
||||
len = _dbus_hash_table_get_n_entries (registry->service_hash);
|
||||
retval = dbus_new (char *, len + 1);
|
||||
|
||||
if (retval == NULL)
|
||||
return FALSE;
|
||||
|
||||
_dbus_hash_iter_init (registry->service_hash, &iter);
|
||||
i = 0;
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
BusService *service = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
retval[i] = _dbus_strdup (service->name);
|
||||
if (retval[i] == NULL)
|
||||
goto error;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
retval[i] = NULL;
|
||||
|
||||
if (array_len)
|
||||
*array_len = len;
|
||||
|
||||
*listp = retval;
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
for (j = 0; j < i; j++)
|
||||
dbus_free (retval[i]);
|
||||
dbus_free (retval);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_service_add_owner (BusService *service,
|
||||
DBusConnection *owner,
|
||||
|
|
@ -232,10 +320,10 @@ bus_service_remove_owner (BusService *service,
|
|||
if (service->owners == NULL)
|
||||
{
|
||||
/* Delete service (already sent message that it was deleted above) */
|
||||
_dbus_hash_table_remove_string (service_hash, service->name);
|
||||
_dbus_hash_table_remove_string (service->registry->service_hash, service->name);
|
||||
|
||||
dbus_free (service->name);
|
||||
_dbus_mem_pool_dealloc (service_pool, service);
|
||||
_dbus_mem_pool_dealloc (service->registry->service_pool, service);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -253,65 +341,6 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
char **
|
||||
bus_services_list (int *array_len)
|
||||
{
|
||||
int i, j, len;
|
||||
char **retval;
|
||||
DBusHashIter iter;
|
||||
|
||||
len = _dbus_hash_table_get_n_entries (service_hash);
|
||||
retval = dbus_new (char *, len + 1);
|
||||
|
||||
if (retval == NULL)
|
||||
return NULL;
|
||||
|
||||
_dbus_hash_iter_init (service_hash, &iter);
|
||||
i = 0;
|
||||
while (_dbus_hash_iter_next (&iter))
|
||||
{
|
||||
BusService *service = _dbus_hash_iter_get_value (&iter);
|
||||
|
||||
retval[i] = _dbus_strdup (service->name);
|
||||
if (retval[i] == NULL)
|
||||
goto error;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
retval[i] = NULL;
|
||||
|
||||
if (array_len)
|
||||
*array_len = len;
|
||||
|
||||
return retval;
|
||||
|
||||
error:
|
||||
for (j = 0; j < i; j++)
|
||||
dbus_free (retval[i]);
|
||||
dbus_free (retval);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bus_service_set_prohibit_replacement (BusService *service,
|
||||
dbus_bool_t prohibit_replacement)
|
||||
|
|
|
|||
|
|
@ -27,26 +27,29 @@
|
|||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-string.h>
|
||||
#include "connection.h"
|
||||
|
||||
/* forward decl that probably shouldn't be in this file */
|
||||
typedef struct BusTransaction BusTransaction;
|
||||
|
||||
/* 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;
|
||||
#include "bus.h"
|
||||
|
||||
typedef void (* BusServiceForeachFunction) (BusService *service,
|
||||
void *data);
|
||||
|
||||
BusService* bus_service_lookup (const DBusString *service_name);
|
||||
BusService* bus_service_ensure (const DBusString *service_name,
|
||||
DBusConnection *owner_if_created,
|
||||
BusTransaction *transaction,
|
||||
DBusError *error);
|
||||
BusRegistry* bus_registry_new (void);
|
||||
void bus_registry_ref (BusRegistry *registry);
|
||||
void bus_registry_unref (BusRegistry *registry);
|
||||
BusService* bus_registry_lookup (BusRegistry *registry,
|
||||
const DBusString *service_name);
|
||||
BusService* bus_registry_ensure (BusRegistry *registry,
|
||||
const DBusString *service_name,
|
||||
DBusConnection *owner_if_created,
|
||||
BusTransaction *transaction,
|
||||
DBusError *error);
|
||||
void bus_registry_foreach (BusRegistry *registry,
|
||||
BusServiceForeachFunction function,
|
||||
void *data);
|
||||
dbus_bool_t bus_registry_list_services (BusRegistry *registry,
|
||||
char ***listp,
|
||||
int *array_len);
|
||||
|
||||
|
||||
dbus_bool_t bus_service_add_owner (BusService *service,
|
||||
DBusConnection *owner,
|
||||
BusTransaction *transaction,
|
||||
|
|
@ -62,10 +65,5 @@ void bus_service_set_prohibit_replacement (BusService
|
|||
dbus_bool_t prohibit_replacement);
|
||||
dbus_bool_t bus_service_get_prohibit_replacement (BusService *service);
|
||||
const char* bus_service_get_name (BusService *service);
|
||||
void bus_service_foreach (BusServiceForeachFunction function,
|
||||
void *data);
|
||||
|
||||
|
||||
char **bus_services_list (int *array_len);
|
||||
|
||||
#endif /* BUS_SERVICES_H */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS)
|
||||
|
||||
if DBUS_BUILD_TESTS
|
||||
TEST_BINARIES=echo-client echo-server unbase64 bus-test break-loader spawn-test
|
||||
TEST_BINARIES=echo-client echo-server unbase64 break-loader spawn-test
|
||||
else
|
||||
TEST_BINARIES=
|
||||
endif
|
||||
|
|
@ -22,13 +22,12 @@ echo_server_SOURCES= \
|
|||
unbase64_SOURCES= \
|
||||
unbase64.c
|
||||
|
||||
|
||||
bus_test_SOURCES = \
|
||||
debug-thread.c \
|
||||
debug-thread.h \
|
||||
bus-test.c \
|
||||
bus-test-loop.c \
|
||||
bus-test-loop.h
|
||||
# bus_test_SOURCES = \
|
||||
# debug-thread.c \
|
||||
# debug-thread.h \
|
||||
# bus-test.c \
|
||||
# bus-test-loop.c \
|
||||
# bus-test-loop.h
|
||||
|
||||
break_loader_SOURCES= \
|
||||
break-loader.c
|
||||
|
|
@ -42,7 +41,7 @@ echo_client_LDADD=$(TEST_LIBS)
|
|||
echo_server_LDADD=$(TEST_LIBS)
|
||||
unbase64_LDADD=$(TEST_LIBS)
|
||||
break_loader_LDADD= $(TEST_LIBS)
|
||||
bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la
|
||||
#bus_test_LDADD=$(TEST_LIBS) $(top_builddir)/bus/libdbus-daemon.la
|
||||
spawn_test_LDADD=$(TEST_LIBS)
|
||||
|
||||
dist-hook:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue