merge from fdo
This commit is contained in:
parent
d6e5ed5f9c
commit
afc679a47d
11 changed files with 140 additions and 70 deletions
|
@ -2,12 +2,9 @@
|
||||||
|
|
||||||
#include <xml.h>
|
#include <xml.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
typedef vector <string> Names;
|
|
||||||
|
|
||||||
static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
|
static const char *DBUS_SERVER_NAME = "org.freedesktop.DBus";
|
||||||
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
|
static const char *DBUS_SERVER_PATH = "/org/freedesktop/DBus";
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -157,6 +157,7 @@ public:
|
||||||
void queue_connection(Connection::Private *);
|
void queue_connection(Connection::Private *);
|
||||||
|
|
||||||
void dispatch_pending();
|
void dispatch_pending();
|
||||||
|
bool has_something_to_dispatch();
|
||||||
|
|
||||||
virtual void enter() = 0;
|
virtual void enter() = 0;
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ class DXXAPI BusDispatcher : public Dispatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BusDispatcher() : _ctx(NULL), _priority(G_PRIORITY_DEFAULT) {}
|
BusDispatcher();
|
||||||
|
~BusDispatcher();
|
||||||
|
|
||||||
void attach(GMainContext *);
|
void attach(GMainContext *);
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ private:
|
||||||
|
|
||||||
GMainContext *_ctx;
|
GMainContext *_ctx;
|
||||||
int _priority;
|
int _priority;
|
||||||
|
GSource *_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace Glib */
|
} /* namespace Glib */
|
||||||
|
|
|
@ -96,7 +96,7 @@ protected:
|
||||||
|
|
||||||
virtual Message _invoke_method(CallMessage &) = 0;
|
virtual Message _invoke_method(CallMessage &) = 0;
|
||||||
|
|
||||||
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
|
virtual bool _invoke_method_noreply(CallMessage &call) = 0;
|
||||||
|
|
||||||
InterfaceProxyTable _interfaces;
|
InterfaceProxyTable _interfaces;
|
||||||
};
|
};
|
||||||
|
|
|
@ -202,7 +202,7 @@ private:
|
||||||
|
|
||||||
Message _invoke_method(CallMessage &);
|
Message _invoke_method(CallMessage &);
|
||||||
|
|
||||||
bool _invoke_method_noreply(CallMessage &call);
|
bool _invoke_method_noreply(CallMessage &call);
|
||||||
|
|
||||||
bool handle_message(const Message &);
|
bool handle_message(const Message &);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
$(dbus_CFLAGS) \
|
$(dbus_CFLAGS) \
|
||||||
$(glib_CFLAGS) \
|
$(glib_CFLAGS) \
|
||||||
$(ecore_CFLAGS) \
|
$(ecore_CFLAGS) \
|
||||||
$(PRIVATE_CFLAGS) \
|
$(PRIVATE_CFLAGS) \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(top_builddir)/include
|
-I$(top_builddir)/include
|
||||||
|
|
|
@ -88,7 +88,7 @@ void Connection::Private::init()
|
||||||
this, &Connection::Private::disconn_filter_function
|
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_dispatch_status_function(conn, dispatch_status_stub, this, 0);
|
||||||
dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
|
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;
|
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()
|
Connection Connection::SystemBus()
|
||||||
{
|
{
|
||||||
return Connection(new Private(DBUS_BUS_SYSTEM));
|
return Connection(new Private(DBUS_BUS_SYSTEM));
|
||||||
|
|
|
@ -63,6 +63,9 @@ struct DXXAPILOCAL Connection::Private
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
DBusDispatchStatus dispatch_status();
|
||||||
|
bool has_something_to_dispatch();
|
||||||
|
|
||||||
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
|
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
|
||||||
|
|
||||||
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);
|
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);
|
||||||
|
|
|
@ -155,10 +155,29 @@ void Dispatcher::queue_connection(Connection::Private *cp)
|
||||||
_mutex_p.unlock();
|
_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()
|
void Dispatcher::dispatch_pending()
|
||||||
{
|
{
|
||||||
_mutex_p.lock();
|
_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)
|
while (_pending_queue.size() > 0)
|
||||||
{
|
{
|
||||||
Connection::PrivatePList::iterator i, j;
|
Connection::PrivatePList::iterator i, j;
|
||||||
|
@ -185,7 +204,7 @@ void DBus::_init_threading()
|
||||||
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
|
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
|
||||||
dbus_threads_init_default();
|
dbus_threads_init_default();
|
||||||
#else
|
#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
|
#endif//DBUS_HAS_THREADS_INIT_DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,10 @@
|
||||||
using namespace DBus;
|
using namespace DBus;
|
||||||
|
|
||||||
Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
|
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()
|
Glib::BusTimeout::~BusTimeout()
|
||||||
|
@ -60,6 +61,9 @@ gboolean Glib::BusTimeout::timeout_handler(gpointer data)
|
||||||
|
|
||||||
void Glib::BusTimeout::_enable()
|
void Glib::BusTimeout::_enable()
|
||||||
{
|
{
|
||||||
|
if (_source)
|
||||||
|
_disable(); // be sane
|
||||||
|
|
||||||
_source = g_timeout_source_new(Timeout::interval());
|
_source = g_timeout_source_new(Timeout::interval());
|
||||||
g_source_set_priority(_source, _priority);
|
g_source_set_priority(_source, _priority);
|
||||||
g_source_set_callback(_source, timeout_handler, this, NULL);
|
g_source_set_callback(_source, timeout_handler, this, NULL);
|
||||||
|
@ -68,7 +72,11 @@ void Glib::BusTimeout::_enable()
|
||||||
|
|
||||||
void Glib::BusTimeout::_disable()
|
void Glib::BusTimeout::_disable()
|
||||||
{
|
{
|
||||||
g_source_destroy(_source);
|
if (_source)
|
||||||
|
{
|
||||||
|
g_source_destroy(_source);
|
||||||
|
_source = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BusSource
|
struct BusSource
|
||||||
|
@ -79,7 +87,7 @@ struct BusSource
|
||||||
|
|
||||||
static gboolean watch_prepare(GSource *source, gint *timeout)
|
static gboolean watch_prepare(GSource *source, gint *timeout)
|
||||||
{
|
{
|
||||||
// debug_log("glib: watch_prepare");
|
//debug_log("glib: watch_prepare");
|
||||||
|
|
||||||
*timeout = -1;
|
*timeout = -1;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -87,7 +95,7 @@ static gboolean watch_prepare(GSource *source, gint *timeout)
|
||||||
|
|
||||||
static gboolean watch_check(GSource *source)
|
static gboolean watch_check(GSource *source)
|
||||||
{
|
{
|
||||||
// debug_log("glib: watch_check");
|
//debug_log("glib: watch_check");
|
||||||
|
|
||||||
BusSource *io = (BusSource *)source;
|
BusSource *io = (BusSource *)source;
|
||||||
return io->poll.revents ? TRUE : FALSE;
|
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");
|
debug_log("glib: watch_dispatch");
|
||||||
|
|
||||||
gboolean cb = callback(data);
|
gboolean cb = callback(data);
|
||||||
DBus::default_dispatcher->dispatch_pending(); //TODO: won't work in case of multiple dispatchers
|
|
||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,9 +117,10 @@ static GSourceFuncs watch_funcs = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
|
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()
|
Glib::BusWatch::~BusWatch()
|
||||||
|
@ -151,6 +159,8 @@ gboolean Glib::BusWatch::watch_handler(gpointer data)
|
||||||
|
|
||||||
void Glib::BusWatch::_enable()
|
void Glib::BusWatch::_enable()
|
||||||
{
|
{
|
||||||
|
if (_source)
|
||||||
|
_disable(); // be sane
|
||||||
_source = g_source_new(&watch_funcs, sizeof(BusSource));
|
_source = g_source_new(&watch_funcs, sizeof(BusSource));
|
||||||
g_source_set_priority(_source, _priority);
|
g_source_set_priority(_source, _priority);
|
||||||
g_source_set_callback(_source, watch_handler, this, NULL);
|
g_source_set_callback(_source, watch_handler, this, NULL);
|
||||||
|
@ -160,8 +170,8 @@ void Glib::BusWatch::_enable()
|
||||||
|
|
||||||
if (flags &DBUS_WATCH_READABLE)
|
if (flags &DBUS_WATCH_READABLE)
|
||||||
condition |= G_IO_IN;
|
condition |= G_IO_IN;
|
||||||
// if (flags &DBUS_WATCH_WRITABLE)
|
if (flags &DBUS_WATCH_WRITABLE)
|
||||||
// condition |= G_IO_OUT;
|
condition |= G_IO_OUT;
|
||||||
if (flags &DBUS_WATCH_ERROR)
|
if (flags &DBUS_WATCH_ERROR)
|
||||||
condition |= G_IO_ERR;
|
condition |= G_IO_ERR;
|
||||||
if (flags &DBUS_WATCH_HANGUP)
|
if (flags &DBUS_WATCH_HANGUP)
|
||||||
|
@ -178,14 +188,91 @@ void Glib::BusWatch::_enable()
|
||||||
|
|
||||||
void Glib::BusWatch::_disable()
|
void Glib::BusWatch::_disable()
|
||||||
{
|
{
|
||||||
|
if (!_source)
|
||||||
|
return;
|
||||||
GPollFD *poll = &(((BusSource *)_source)->poll);
|
GPollFD *poll = &(((BusSource *)_source)->poll);
|
||||||
g_source_remove_poll(_source, poll);
|
g_source_remove_poll(_source, poll);
|
||||||
g_source_destroy(_source);
|
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)
|
void Glib::BusDispatcher::attach(GMainContext *ctx)
|
||||||
{
|
{
|
||||||
|
g_assert(_ctx == NULL); // just to be sane
|
||||||
|
|
||||||
_ctx = ctx ? ctx : g_main_context_default();
|
_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)
|
Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue