merge from fdo

This commit is contained in:
Andreas Volz 2009-01-08 22:11:38 +01:00
parent d6e5ed5f9c
commit afc679a47d
11 changed files with 140 additions and 70 deletions

View file

@ -2,12 +2,9 @@
#include <xml.h>
#include <iostream>
#include <vector>
using namespace std;
typedef vector <string> Names;
static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";

View file

@ -1,50 +0,0 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "props-server.h"
#include <signal.h>
static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties";
static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties";
PropsServer::PropsServer(DBus::Connection &connection)
: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH)
{
Version = 1;
Message = "default message";
}
void PropsServer::on_set_property
(DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value)
{
if (property == "Message")
{
std::string msg = value;
this->MessageChanged(msg);
}
}
DBus::BusDispatcher dispatcher;
void niam(int sig)
{
dispatcher.leave();
}
int main()
{
signal(SIGTERM, niam);
signal(SIGINT, niam);
DBus::default_dispatcher = &dispatcher;
DBus::Connection conn = DBus::Connection::SessionBus();
conn.request_name(PROPS_SERVER_NAME);
PropsServer server(conn);
dispatcher.enter();
return 0;
}

View file

@ -157,6 +157,7 @@ public:
void queue_connection(Connection::Private *);
void dispatch_pending();
bool has_something_to_dispatch();
virtual void enter() = 0;

View file

@ -90,7 +90,8 @@ class DXXAPI BusDispatcher : public Dispatcher
{
public:
BusDispatcher() : _ctx(NULL), _priority(G_PRIORITY_DEFAULT) {}
BusDispatcher();
~BusDispatcher();
void attach(GMainContext *);
@ -112,6 +113,7 @@ private:
GMainContext *_ctx;
int _priority;
GSource *_source;
};
} /* namespace Glib */

View file

@ -95,8 +95,8 @@ protected:
{}
virtual Message _invoke_method(CallMessage &) = 0;
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
InterfaceProxyTable _interfaces;
};

View file

@ -202,7 +202,7 @@ private:
Message _invoke_method(CallMessage &);
bool _invoke_method_noreply(CallMessage &call);
bool _invoke_method_noreply(CallMessage &call);
bool handle_message(const Message &);

View file

@ -1,7 +1,7 @@
AM_CPPFLAGS = \
$(dbus_CFLAGS) \
$(glib_CFLAGS) \
$(ecore_CFLAGS) \
$(ecore_CFLAGS) \
$(PRIVATE_CFLAGS) \
-I$(top_srcdir)/include \
-I$(top_builddir)/include

View file

@ -88,7 +88,7 @@ void Connection::Private::init()
this, &Connection::Private::disconn_filter_function
);
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL);
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least
dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0);
dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
@ -175,6 +175,17 @@ bool Connection::Private::disconn_filter_function(const Message &msg)
return false;
}
DBusDispatchStatus Connection::Private::dispatch_status()
{
return dbus_connection_get_dispatch_status(conn);
}
bool Connection::Private::has_something_to_dispatch()
{
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
}
Connection Connection::SystemBus()
{
return Connection(new Private(DBUS_BUS_SYSTEM));

View file

@ -63,6 +63,9 @@ struct DXXAPILOCAL Connection::Private
void init();
DBusDispatchStatus dispatch_status();
bool has_something_to_dispatch();
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);

View file

@ -155,10 +155,29 @@ void Dispatcher::queue_connection(Connection::Private *cp)
_mutex_p.unlock();
}
bool Dispatcher::has_something_to_dispatch()
{
_mutex_p.lock();
bool has_something = false;
for(Connection::PrivatePList::iterator it = _pending_queue.begin();
it != _pending_queue.end() && !has_something;
++it)
{
has_something = (*it)->has_something_to_dispatch();
}
_mutex_p.unlock();
return has_something;
}
void Dispatcher::dispatch_pending()
{
_mutex_p.lock();
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
while (_pending_queue.size() > 0)
{
Connection::PrivatePList::iterator i, j;
@ -185,7 +204,7 @@ void DBus::_init_threading()
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
dbus_threads_init_default();
#else
debug_log("Thread support is not enabled! Your D-Bus version is too old!");
debug_log("Thread support is not enabled! Your D-Bus version is too old!");
#endif//DBUS_HAS_THREADS_INIT_DEFAULT
}

View file

@ -31,9 +31,10 @@
using namespace DBus;
Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
: Timeout(ti), _ctx(ctx), _priority(priority)
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
{
_enable();
if (Timeout::enabled())
_enable();
}
Glib::BusTimeout::~BusTimeout()
@ -60,6 +61,9 @@ gboolean Glib::BusTimeout::timeout_handler(gpointer data)
void Glib::BusTimeout::_enable()
{
if (_source)
_disable(); // be sane
_source = g_timeout_source_new(Timeout::interval());
g_source_set_priority(_source, _priority);
g_source_set_callback(_source, timeout_handler, this, NULL);
@ -68,7 +72,11 @@ void Glib::BusTimeout::_enable()
void Glib::BusTimeout::_disable()
{
g_source_destroy(_source);
if (_source)
{
g_source_destroy(_source);
_source = NULL;
}
}
struct BusSource
@ -79,7 +87,7 @@ struct BusSource
static gboolean watch_prepare(GSource *source, gint *timeout)
{
// debug_log("glib: watch_prepare");
//debug_log("glib: watch_prepare");
*timeout = -1;
return FALSE;
@ -87,7 +95,7 @@ static gboolean watch_prepare(GSource *source, gint *timeout)
static gboolean watch_check(GSource *source)
{
// debug_log("glib: watch_check");
//debug_log("glib: watch_check");
BusSource *io = (BusSource *)source;
return io->poll.revents ? TRUE : FALSE;
@ -98,7 +106,6 @@ static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer d
debug_log("glib: watch_dispatch");
gboolean cb = callback(data);
DBus::default_dispatcher->dispatch_pending(); //TODO: won't work in case of multiple dispatchers
return cb;
}
@ -110,9 +117,10 @@ static GSourceFuncs watch_funcs = {
};
Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
: Watch(wi), _ctx(ctx), _priority(priority)
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
{
_enable();
if (Watch::enabled())
_enable();
}
Glib::BusWatch::~BusWatch()
@ -151,6 +159,8 @@ gboolean Glib::BusWatch::watch_handler(gpointer data)
void Glib::BusWatch::_enable()
{
if (_source)
_disable(); // be sane
_source = g_source_new(&watch_funcs, sizeof(BusSource));
g_source_set_priority(_source, _priority);
g_source_set_callback(_source, watch_handler, this, NULL);
@ -160,8 +170,8 @@ void Glib::BusWatch::_enable()
if (flags &DBUS_WATCH_READABLE)
condition |= G_IO_IN;
// if (flags &DBUS_WATCH_WRITABLE)
// condition |= G_IO_OUT;
if (flags &DBUS_WATCH_WRITABLE)
condition |= G_IO_OUT;
if (flags &DBUS_WATCH_ERROR)
condition |= G_IO_ERR;
if (flags &DBUS_WATCH_HANGUP)
@ -178,14 +188,91 @@ void Glib::BusWatch::_enable()
void Glib::BusWatch::_disable()
{
if (!_source)
return;
GPollFD *poll = &(((BusSource *)_source)->poll);
g_source_remove_poll(_source, poll);
g_source_destroy(_source);
_source = NULL;
}
/*
* We need this on top of the IO handlers, because sometimes
* there are messages to dispatch queued up but no IO pending.
* (fixes also a previous problem of code not working in case of multiple dispatchers)
*/
struct DispatcherSource
{
GSource source;
Dispatcher *dispatcher;
};
static gboolean dispatcher_prepare(GSource *source, gint *timeout)
{
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
*timeout = -1;
return dispatcher->has_something_to_dispatch()? TRUE:FALSE;
}
static gboolean dispatcher_check(GSource *source)
{
return FALSE;
}
static gboolean
dispatcher_dispatch(GSource *source,
GSourceFunc callback,
gpointer user_data)
{
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
dispatcher->dispatch_pending();
return TRUE;
}
static const GSourceFuncs dispatcher_funcs = {
dispatcher_prepare,
dispatcher_check,
dispatcher_dispatch,
NULL
};
Glib::BusDispatcher::BusDispatcher()
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
{
}
Glib::BusDispatcher::~BusDispatcher()
{
if (_source)
{
GSource *temp = _source;
_source = NULL;
g_source_destroy (temp);
g_source_unref (temp);
}
if (_ctx)
g_main_context_unref(_ctx);
}
void Glib::BusDispatcher::attach(GMainContext *ctx)
{
g_assert(_ctx == NULL); // just to be sane
_ctx = ctx ? ctx : g_main_context_default();
g_main_context_ref(_ctx);
// create the source for dispatching messages
_source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
sizeof(DispatcherSource));
((DispatcherSource*)_source)->dispatcher = this;
g_source_attach (_source, _ctx);
}
Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi)