- NO FUNCTIONAL CODE CHANGES!!!!

- changed code formating from tabs to spaces and others
- used astyle with this option:
  --style=ansi --indent=spaces=2 -M --pad-oper --unpad-paren --pad-header --align-pointer=name --lineend=linux
This commit is contained in:
Andreas Volz 2011-11-28 12:44:11 +01:00
parent b100e9d32a
commit 1c8e43e6d6
76 changed files with 5691 additions and 5492 deletions

View file

@ -42,432 +42,433 @@
using namespace DBus;
Connection::Private::Private(DBusConnection *c, Server::Private *s)
: conn(c) , dispatcher(NULL), server(s)
: conn(c) , dispatcher(NULL), server(s)
{
init();
init();
}
Connection::Private::Private(DBusBusType type)
: dispatcher(NULL), server(NULL)
{
InternalError e;
InternalError e;
conn = dbus_bus_get_private(type, e);
conn = dbus_bus_get_private(type, e);
if (e) throw Error(e);
if (e) throw Error(e);
init();
init();
}
Connection::Private::~Private()
{
debug_log("terminating connection 0x%08x", conn);
debug_log("terminating connection 0x%08x", conn);
detach_server();
detach_server();
if (dbus_connection_get_is_connected(conn))
{
std::vector<std::string>::iterator i = names.begin();
if (dbus_connection_get_is_connected(conn))
{
std::vector<std::string>::iterator i = names.begin();
while (i != names.end())
{
debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
dbus_bus_release_name(conn, i->c_str(), NULL);
++i;
}
dbus_connection_close(conn);
}
dbus_connection_unref(conn);
while (i != names.end())
{
debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
dbus_bus_release_name(conn, i->c_str(), NULL);
++i;
}
dbus_connection_close(conn);
}
dbus_connection_unref(conn);
}
void Connection::Private::init()
{
dbus_connection_ref(conn);
dbus_connection_ref(conn); //todo: the library has to own another reference
dbus_connection_ref(conn);
dbus_connection_ref(conn); //todo: the library has to own another reference
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
this, &Connection::Private::disconn_filter_function
);
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
this, &Connection::Private::disconn_filter_function
);
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least
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??
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??
}
void Connection::Private::detach_server()
{
/* Server::Private *tmp = server;
/* Server::Private *tmp = server;
server = NULL;
server = NULL;
if (tmp)
{
ConnectionList::iterator i;
if (tmp)
{
ConnectionList::iterator i;
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
{
if (i->_pvt.get() == this)
{
tmp->connections.erase(i);
break;
}
}
}*/
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
{
if (i->_pvt.get() == this)
{
tmp->connections.erase(i);
break;
}
}
}*/
}
bool Connection::Private::do_dispatch()
{
debug_log("dispatching on %p", conn);
debug_log("dispatching on %p", conn);
if (!dbus_connection_get_is_connected(conn))
{
debug_log("connection terminated");
if (!dbus_connection_get_is_connected(conn))
{
debug_log("connection terminated");
detach_server();
detach_server();
return true;
}
return true;
}
return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
}
void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status, void *data)
{
Private *p = static_cast<Private *>(data);
Private *p = static_cast<Private *>(data);
switch (status)
{
case DBUS_DISPATCH_DATA_REMAINS:
debug_log("some dispatching to do on %p", dc);
p->dispatcher->queue_connection(p);
break;
switch (status)
{
case DBUS_DISPATCH_DATA_REMAINS:
debug_log("some dispatching to do on %p", dc);
p->dispatcher->queue_connection(p);
break;
case DBUS_DISPATCH_COMPLETE:
debug_log("all dispatching done on %p", dc);
break;
case DBUS_DISPATCH_COMPLETE:
debug_log("all dispatching done on %p", dc);
break;
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
debug_log("connection %p needs memory", dc);
break;
}
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
debug_log("connection %p needs memory", dc);
break;
}
}
DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg, void *data)
{
MessageSlot *slot = static_cast<MessageSlot *>(data);
MessageSlot *slot = static_cast<MessageSlot *>(data);
Message msg = Message(new Message::Private(dmsg));
Message msg = Message(new Message::Private(dmsg));
return slot && !slot->empty() && slot->call(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
return slot && !slot->empty() && slot->call(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
bool Connection::Private::disconn_filter_function(const Message &msg)
{
if (msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected"))
{
debug_log("%p disconnected by local bus", conn);
dbus_connection_close(conn);
if (msg.is_signal(DBUS_INTERFACE_LOCAL, "Disconnected"))
{
debug_log("%p disconnected by local bus", conn);
dbus_connection_close(conn);
return true;
}
return false;
return true;
}
return false;
}
DBusDispatchStatus Connection::Private::dispatch_status()
{
return dbus_connection_get_dispatch_status(conn);
return dbus_connection_get_dispatch_status(conn);
}
bool Connection::Private::has_something_to_dispatch()
{
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
}
Connection Connection::SystemBus()
{
return Connection(new Private(DBUS_BUS_SYSTEM));
return Connection(new Private(DBUS_BUS_SYSTEM));
}
Connection Connection::SessionBus()
{
return Connection(new Private(DBUS_BUS_SESSION));
return Connection(new Private(DBUS_BUS_SESSION));
}
Connection Connection::ActivationBus()
{
return Connection(new Private(DBUS_BUS_STARTER));
return Connection(new Private(DBUS_BUS_STARTER));
}
Connection::Connection(const char *address, bool priv)
: _timeout(-1)
: _timeout(-1)
{
InternalError e;
DBusConnection *conn = priv
? dbus_connection_open_private(address, e)
: dbus_connection_open(address, e);
InternalError e;
DBusConnection *conn = priv
? dbus_connection_open_private(address, e)
: dbus_connection_open(address, e);
if (e) throw Error(e);
if (e) throw Error(e);
_pvt = new Private(conn);
_pvt = new Private(conn);
setup(default_dispatcher);
setup(default_dispatcher);
debug_log("connected to %s", address);
debug_log("connected to %s", address);
}
Connection::Connection(Connection::Private *p)
: _pvt(p), _timeout(-1)
: _pvt(p), _timeout(-1)
{
setup(default_dispatcher);
setup(default_dispatcher);
}
Connection::Connection(const Connection &c)
: _pvt(c._pvt),_timeout(c._timeout)
: _pvt(c._pvt), _timeout(c._timeout)
{
dbus_connection_ref(_pvt->conn);
dbus_connection_ref(_pvt->conn);
}
Connection::~Connection()
{
dbus_connection_unref(_pvt->conn);
dbus_connection_unref(_pvt->conn);
}
Dispatcher *Connection::setup(Dispatcher *dispatcher)
{
debug_log("registering stubs for connection %p", _pvt->conn);
debug_log("registering stubs for connection %p", _pvt->conn);
if (!dispatcher) dispatcher = default_dispatcher;
if (!dispatcher) dispatcher = default_dispatcher;
if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");
if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");
Dispatcher *prev = _pvt->dispatcher;
Dispatcher *prev = _pvt->dispatcher;
_pvt->dispatcher = dispatcher;
_pvt->dispatcher = dispatcher;
dispatcher->queue_connection(_pvt.get());
dispatcher->queue_connection(_pvt.get());
dbus_connection_set_watch_functions(
_pvt->conn,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_connection_set_watch_functions(
_pvt->conn,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_connection_set_timeout_functions(
_pvt->conn,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
dbus_connection_set_timeout_functions(
_pvt->conn,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
return prev;
return prev;
}
bool Connection::operator == (const Connection &c) const
{
return _pvt->conn == c._pvt->conn;
return _pvt->conn == c._pvt->conn;
}
bool Connection::register_bus()
{
InternalError e;
InternalError e;
bool r = dbus_bus_register(_pvt->conn, e);
if (e) throw (e);
bool r = dbus_bus_register(_pvt->conn, e);
return r;
if (e) throw(e);
return r;
}
bool Connection::connected() const
{
return dbus_connection_get_is_connected(_pvt->conn);
return dbus_connection_get_is_connected(_pvt->conn);
}
void Connection::disconnect()
{
// dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x
dbus_connection_close(_pvt->conn);
dbus_connection_close(_pvt->conn);
}
void Connection::exit_on_disconnect(bool exit)
{
dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
}
bool Connection::unique_name(const char *n)
{
return dbus_bus_set_unique_name(_pvt->conn, n);
return dbus_bus_set_unique_name(_pvt->conn, n);
}
const char *Connection::unique_name() const
{
return dbus_bus_get_unique_name(_pvt->conn);
return dbus_bus_get_unique_name(_pvt->conn);
}
void Connection::flush()
{
dbus_connection_flush(_pvt->conn);
dbus_connection_flush(_pvt->conn);
}
void Connection::add_match(const char *rule)
{
InternalError e;
InternalError e;
dbus_bus_add_match(_pvt->conn, rule, e);
dbus_bus_add_match(_pvt->conn, rule, e);
debug_log("%s: added match rule %s", unique_name(), rule);
debug_log("%s: added match rule %s", unique_name(), rule);
if (e) throw Error(e);
if (e) throw Error(e);
}
void Connection::remove_match(const char *rule,
bool throw_on_error)
bool throw_on_error)
{
InternalError e;
dbus_bus_remove_match(_pvt->conn, rule, e);
InternalError e;
debug_log("%s: removed match rule %s", unique_name(), rule);
dbus_bus_remove_match(_pvt->conn, rule, e);
if (e) {
if (throw_on_error)
throw Error(e);
else
debug_log("DBus::Connection::remove_match: %s (%s).",
static_cast<DBusError*>(e)->message,
static_cast<DBusError*>(e)->name);
}
debug_log("%s: removed match rule %s", unique_name(), rule);
if (e)
{
if (throw_on_error)
throw Error(e);
else
debug_log("DBus::Connection::remove_match: %s (%s).",
static_cast<DBusError *>(e)->message,
static_cast<DBusError *>(e)->name);
}
}
bool Connection::add_filter(MessageSlot &s)
{
debug_log("%s: adding filter", unique_name());
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
debug_log("%s: adding filter", unique_name());
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
}
void Connection::remove_filter(MessageSlot &s)
{
debug_log("%s: removing filter", unique_name());
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
debug_log("%s: removing filter", unique_name());
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
}
bool Connection::send(const Message &msg, unsigned int *serial)
{
return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
}
Message Connection::send_blocking(Message &msg, int timeout)
{
DBusMessage *reply;
InternalError e;
if (this->_timeout != -1)
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
}
else
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
}
DBusMessage *reply;
InternalError e;
if (e) throw Error(e);
if (this->_timeout != -1)
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
}
else
{
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
}
return Message(new Message::Private(reply), false);
if (e) throw Error(e);
return Message(new Message::Private(reply), false);
}
PendingCall Connection::send_async(Message &msg, int timeout)
{
DBusPendingCall *pending;
DBusPendingCall *pending;
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
{
throw ErrorNoMemory("Unable to start asynchronous call");
}
return PendingCall(new PendingCall::Private(pending));
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
{
throw ErrorNoMemory("Unable to start asynchronous call");
}
return PendingCall(new PendingCall::Private(pending));
}
void Connection::request_name(const char *name, int flags)
{
InternalError e;
InternalError e;
debug_log("%s: registering bus name %s", unique_name(), name);
debug_log("%s: registering bus name %s", unique_name(), name);
/*
* TODO:
* Think about giving back the 'ret' value. Some people on the list
* requested about this...
*/
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
/*
* TODO:
* Think about giving back the 'ret' value. Some people on the list
* requested about this...
*/
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
if (ret == -1)
{
if (e) throw Error(e);
}
if (ret == -1)
{
if (e) throw Error(e);
}
// this->remove_match("destination");
if (name)
{
_pvt->names.push_back(name);
std::string match = "destination='" + _pvt->names.back() + "'";
add_match(match.c_str());
}
if (name)
{
_pvt->names.push_back(name);
std::string match = "destination='" + _pvt->names.back() + "'";
add_match(match.c_str());
}
}
unsigned long Connection::sender_unix_uid(const char *sender)
{
InternalError e;
unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
if (e) throw Error(e);
return ul;
InternalError e;
unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
if (e) throw Error(e);
return ul;
}
bool Connection::has_name(const char *name)
{
InternalError e;
{
InternalError e;
bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);
bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);
if (e) throw Error(e);
if (e) throw Error(e);
return b;
return b;
}
const std::vector<std::string>& Connection::names()
{
return _pvt->names;
return _pvt->names;
}
bool Connection::start_service(const char *name, unsigned long flags)
{
InternalError e;
InternalError e;
bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);
bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);
if (e) throw Error(e);
return b;
if (e) throw Error(e);
return b;
}
void Connection::set_timeout(int timeout)
{
_timeout=timeout;
}
int Connection::get_timeout()
{
return _timeout;
_timeout = timeout;
}
int Connection::get_timeout()
{
return _timeout;
}

View file

@ -38,37 +38,38 @@
#include <string>
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL Connection::Private
{
DBusConnection * conn;
DBusConnection *conn;
std::vector<std::string> names;
std::vector<std::string> names;
Dispatcher *dispatcher;
bool do_dispatch();
Dispatcher *dispatcher;
bool do_dispatch();
MessageSlot disconn_filter;
bool disconn_filter_function(const Message &);
MessageSlot disconn_filter;
bool disconn_filter_function(const Message &);
Server::Private *server;
void detach_server();
Server::Private *server;
void detach_server();
Private(DBusConnection *, Server::Private * = NULL);
Private(DBusConnection *, Server::Private * = NULL);
Private(DBusBusType);
Private(DBusBusType);
~Private();
~Private();
void init();
void init();
DBusDispatchStatus dispatch_status();
bool has_something_to_dispatch();
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 *);
};
} /* namespace DBus */

View file

@ -35,19 +35,19 @@ static void _debug_log_default(const char *format, ...)
{
//#ifdef DEBUG
static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
if (debug_env)
{
va_list args;
va_start(args, format);
if (debug_env)
{
va_list args;
va_start(args, format);
fprintf(stderr, "dbus-c++: ");
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fprintf(stderr, "dbus-c++: ");
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
va_end(args);
}
va_end(args);
}
//#endif//DEBUG
}

View file

@ -38,64 +38,64 @@ DBus::Dispatcher *DBus::default_dispatcher = NULL;
using namespace DBus;
Timeout::Timeout(Timeout::Internal *i)
: _int(i)
: _int(i)
{
dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
}
int Timeout::interval() const
{
return dbus_timeout_get_interval((DBusTimeout *)_int);
return dbus_timeout_get_interval((DBusTimeout *)_int);
}
bool Timeout::enabled() const
{
return dbus_timeout_get_enabled((DBusTimeout *)_int);
return dbus_timeout_get_enabled((DBusTimeout *)_int);
}
bool Timeout::handle()
{
return dbus_timeout_handle((DBusTimeout *)_int);
return dbus_timeout_handle((DBusTimeout *)_int);
}
/*
*/
Watch::Watch(Watch::Internal *i)
: _int(i)
: _int(i)
{
dbus_watch_set_data((DBusWatch *)i, this, NULL);
dbus_watch_set_data((DBusWatch *)i, this, NULL);
}
int Watch::descriptor() const
{
#if HAVE_WIN32
return dbus_watch_get_socket((DBusWatch*)_int);
return dbus_watch_get_socket((DBusWatch *)_int);
#else
// check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
// check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
(DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \
(DBUS_VERSION_MAJOR > 1)
return dbus_watch_get_unix_fd((DBusWatch*)_int);
#else
return dbus_watch_get_fd((DBusWatch*)_int);
#endif
return dbus_watch_get_unix_fd((DBusWatch *)_int);
#else
return dbus_watch_get_fd((DBusWatch *)_int);
#endif
#endif
}
int Watch::flags() const
{
return dbus_watch_get_flags((DBusWatch *)_int);
return dbus_watch_get_flags((DBusWatch *)_int);
}
bool Watch::enabled() const
{
return dbus_watch_get_enabled((DBusWatch *)_int);
return dbus_watch_get_enabled((DBusWatch *)_int);
}
bool Watch::handle(int flags)
{
return dbus_watch_handle((DBusWatch *)_int, flags);
return dbus_watch_handle((DBusWatch *)_int, flags);
}
/*
@ -103,216 +103,218 @@ bool Watch::handle(int flags)
dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
{
Dispatcher *d = static_cast<Dispatcher *>(data);
Dispatcher *d = static_cast<Dispatcher *>(data);
Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
d->add_watch(w);
d->add_watch(w);
return true;
return true;
}
void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
{
Dispatcher *d = static_cast<Dispatcher *>(data);
Dispatcher *d = static_cast<Dispatcher *>(data);
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
d->rem_watch(w);
d->rem_watch(w);
}
void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
{
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
w->toggle();
w->toggle();
}
dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
{
Dispatcher *d = static_cast<Dispatcher *>(data);
Dispatcher *d = static_cast<Dispatcher *>(data);
Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
d->add_timeout(t);
d->add_timeout(t);
return true;
return true;
}
void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
{
Dispatcher *d = static_cast<Dispatcher *>(data);
Dispatcher *d = static_cast<Dispatcher *>(data);
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
d->rem_timeout(t);
d->rem_timeout(t);
}
void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
{
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
t->toggle();
t->toggle();
}
void Dispatcher::queue_connection(Connection::Private *cp)
{
_mutex_p.lock();
_pending_queue.push_back(cp);
_mutex_p.unlock();
_mutex_p.lock();
_pending_queue.push_back(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.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;
_mutex_p.unlock();
return has_something;
}
void Dispatcher::dispatch_pending()
{
while (1)
{
_mutex_p.lock();
if (_pending_queue.empty())
{
_mutex_p.unlock();
break;
}
while (1)
{
_mutex_p.lock();
if (_pending_queue.empty())
{
_mutex_p.unlock();
break;
}
Connection::PrivatePList pending_queue_copy(_pending_queue);
_mutex_p.unlock();
Connection::PrivatePList pending_queue_copy(_pending_queue);
_mutex_p.unlock();
size_t copy_elem_num(pending_queue_copy.size());
size_t copy_elem_num(pending_queue_copy.size());
dispatch_pending(pending_queue_copy);
dispatch_pending(pending_queue_copy);
//only push_back on list is mandatory!
_mutex_p.lock();
//only push_back on list is mandatory!
_mutex_p.lock();
Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin();
size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end())
{
j = i;
++j;
_pending_queue.erase(i);
i = j;
++counter;
}
Connection::PrivatePList::iterator i, j;
i = _pending_queue.begin();
size_t counter = 0;
while (counter < copy_elem_num && i != _pending_queue.end())
{
j = i;
++j;
_pending_queue.erase(i);
i = j;
++counter;
}
_mutex_p.unlock();
}
_mutex_p.unlock();
}
}
void Dispatcher::dispatch_pending(Connection::PrivatePList& pending_queue)
void Dispatcher::dispatch_pending(Connection::PrivatePList &pending_queue)
{
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
_mutex_p_copy.lock();
while (pending_queue.size() > 0)
{
Connection::PrivatePList::iterator i, j;
_mutex_p_copy.lock();
while (pending_queue.size() > 0)
{
Connection::PrivatePList::iterator i, j;
i = pending_queue.begin();
i = pending_queue.begin();
while (i != pending_queue.end())
{
j = i;
while (i != pending_queue.end())
{
j = i;
++j;
++j;
if ((*i)->do_dispatch())
pending_queue.erase(i);
else
debug_log("dispatch_pending_private: do_dispatch error");
if ((*i)->do_dispatch())
pending_queue.erase(i);
else
debug_log("dispatch_pending_private: do_dispatch error");
i = j;
}
}
_mutex_p_copy.unlock();
i = j;
}
}
_mutex_p_copy.unlock();
}
void DBus::_init_threading()
{
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
dbus_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
}
void DBus::_init_threading(
MutexNewFn m1,
MutexFreeFn m2,
MutexLockFn m3,
MutexUnlockFn m4,
CondVarNewFn c1,
CondVarFreeFn c2,
CondVarWaitFn c3,
CondVarWaitTimeoutFn c4,
CondVarWakeOneFn c5,
CondVarWakeAllFn c6
MutexNewFn m1,
MutexFreeFn m2,
MutexLockFn m3,
MutexUnlockFn m4,
CondVarNewFn c1,
CondVarFreeFn c2,
CondVarWaitFn c3,
CondVarWaitTimeoutFn c4,
CondVarWakeOneFn c5,
CondVarWakeAllFn c6
)
{
#ifndef DBUS_HAS_RECURSIVE_MUTEX
DBusThreadFunctions functions = {
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusMutexNewFunction) m1,
(DBusMutexFreeFunction) m2,
(DBusMutexLockFunction) m3,
(DBusMutexUnlockFunction) m4,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6
};
DBusThreadFunctions functions =
{
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
(DBusMutexNewFunction) m1,
(DBusMutexFreeFunction) m2,
(DBusMutexLockFunction) m3,
(DBusMutexUnlockFunction) m4,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6
};
#else
DBusThreadFunctions functions = {
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
0, 0, 0, 0,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6,
(DBusRecursiveMutexNewFunction) m1,
(DBusRecursiveMutexFreeFunction) m2,
(DBusRecursiveMutexLockFunction) m3,
(DBusRecursiveMutexUnlockFunction) m4
};
DBusThreadFunctions functions =
{
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
0, 0, 0, 0,
(DBusCondVarNewFunction) c1,
(DBusCondVarFreeFunction) c2,
(DBusCondVarWaitFunction) c3,
(DBusCondVarWaitTimeoutFunction) c4,
(DBusCondVarWakeOneFunction) c5,
(DBusCondVarWakeAllFunction) c6,
(DBusRecursiveMutexNewFunction) m1,
(DBusRecursiveMutexFreeFunction) m2,
(DBusRecursiveMutexLockFunction) m3,
(DBusRecursiveMutexUnlockFunction) m4
};
#endif//DBUS_HAS_RECURSIVE_MUTEX
dbus_threads_init(&functions);
dbus_threads_init(&functions);
}

View file

@ -35,21 +35,22 @@
#include "internalerror.h"
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL Dispatcher::Private
{
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data);
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data);
static void on_rem_watch(DBusWatch *watch, void *data);
static void on_rem_watch(DBusWatch *watch, void *data);
static void on_toggle_watch(DBusWatch *watch, void *data);
static void on_toggle_watch(DBusWatch *watch, void *data);
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data);
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data);
static void on_rem_timeout(DBusTimeout *timeout, void *data);
static void on_rem_timeout(DBusTimeout *timeout, void *data);
static void on_toggle_timeout(DBusTimeout *timeout, void *data);
static void on_toggle_timeout(DBusTimeout *timeout, void *data);
};
} /* namespace DBus */

View file

@ -33,120 +33,120 @@ using namespace DBus;
Dispatcher *gdispatcher = NULL;
Ecore::BusTimeout::BusTimeout( Timeout::Internal* ti)
: Timeout(ti)
Ecore::BusTimeout::BusTimeout(Timeout::Internal *ti)
: Timeout(ti)
{
if (Timeout::enabled())
{
_enable();
_enable();
}
}
Ecore::BusTimeout::~BusTimeout()
{
_disable();
_disable();
}
void Ecore::BusTimeout::toggle()
{
debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
if(Timeout::enabled())
if (Timeout::enabled())
{
_enable();
}
else
else
{
_disable();
}
}
Eina_Bool Ecore::BusTimeout::timeout_handler( void *data )
Eina_Bool Ecore::BusTimeout::timeout_handler(void *data)
{
Ecore::BusTimeout* t = reinterpret_cast<Ecore::BusTimeout*>(data);
Ecore::BusTimeout *t = reinterpret_cast<Ecore::BusTimeout *>(data);
debug_log("Ecore::BusTimeout::timeout_handler( void *data )");
debug_log("Ecore::BusTimeout::timeout_handler( void *data )");
t->handle();
t->handle();
return ECORE_CALLBACK_RENEW;
return ECORE_CALLBACK_RENEW;
}
void Ecore::BusTimeout::_enable()
{
debug_log("Ecore::BusTimeout::_enable()");
_etimer = ecore_timer_add (((double)Timeout::interval())/1000, timeout_handler, this);
_etimer = ecore_timer_add(((double)Timeout::interval()) / 1000, timeout_handler, this);
}
void Ecore::BusTimeout::_disable()
{
debug_log("Ecore::BusTimeout::_disable()");
ecore_timer_del (_etimer);
ecore_timer_del(_etimer);
}
Ecore::BusWatch::BusWatch( Watch::Internal* wi)
: Watch(wi), fd_handler (NULL), _bd (NULL)
{
Ecore::BusWatch::BusWatch(Watch::Internal *wi)
: Watch(wi), fd_handler(NULL), _bd(NULL)
{
if (Watch::enabled())
{
_enable();
_enable();
}
}
Ecore::BusWatch::~BusWatch()
{
_disable();
_disable();
}
void Ecore::BusWatch::toggle()
{
debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
if(Watch::enabled()) _enable();
else _disable();
if (Watch::enabled()) _enable();
else _disable();
}
Eina_Bool Ecore::BusWatch::watch_dispatch( void *data, Ecore_Fd_Handler *fdh )
Eina_Bool Ecore::BusWatch::watch_dispatch(void *data, Ecore_Fd_Handler *fdh)
{
Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*>(data);
Ecore::BusWatch *w = reinterpret_cast<Ecore::BusWatch *>(data);
debug_log("Ecore::BusWatch watch_handler");
debug_log("Ecore::BusWatch watch_handler");
int flags = w->flags();
int flags = w->flags();
if (w->flags() & DBUS_WATCH_READABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
if (w->flags() & DBUS_WATCH_WRITABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
if (w->flags() & DBUS_WATCH_READABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
if (w->flags() & DBUS_WATCH_WRITABLE)
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
w->handle(flags);
w->_bd->dispatch_pending();
return 1;
return 1;
}
void Ecore::BusWatch::_enable()
{
debug_log("Ecore::BusWatch::_enable()");
fd_handler = ecore_main_fd_handler_add (descriptor(),
(Ecore_Fd_Handler_Flags) (ECORE_FD_READ | ECORE_FD_WRITE),
watch_dispatch, this,
NULL, NULL);
fd_handler = ecore_main_fd_handler_add(descriptor(),
(Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_WRITE),
watch_dispatch, this,
NULL, NULL);
}
void Ecore::BusWatch::_disable()
{
if (fd_handler)
{
ecore_main_fd_handler_del (fd_handler);
ecore_main_fd_handler_del(fd_handler);
fd_handler = NULL;
}
}
void Ecore::BusWatch::data (Ecore::BusDispatcher *bd)
void Ecore::BusWatch::data(Ecore::BusDispatcher *bd)
{
_bd = bd;
}
@ -155,41 +155,41 @@ Ecore::BusDispatcher::BusDispatcher()
{
}
Eina_Bool Ecore::BusDispatcher::check ( void *data, Ecore_Fd_Handler *fdh)
Eina_Bool Ecore::BusDispatcher::check(void *data, Ecore_Fd_Handler *fdh)
{
return 0;
}
Timeout* Ecore::BusDispatcher::add_timeout( Timeout::Internal* wi )
Timeout *Ecore::BusDispatcher::add_timeout(Timeout::Internal *wi)
{
Timeout* t = new Ecore::BusTimeout( wi );
Timeout *t = new Ecore::BusTimeout(wi);
debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on":"off");
debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
return t;
return t;
}
void Ecore::BusDispatcher::rem_timeout( Timeout* t )
void Ecore::BusDispatcher::rem_timeout(Timeout *t)
{
debug_log("ecore: removed timeout %p", t);
debug_log("ecore: removed timeout %p", t);
delete t;
delete t;
}
Watch* Ecore::BusDispatcher::add_watch( Watch::Internal* wi )
Watch *Ecore::BusDispatcher::add_watch(Watch::Internal *wi)
{
Ecore::BusWatch* w = new Ecore::BusWatch(wi);
w->data (this);
Ecore::BusWatch *w = new Ecore::BusWatch(wi);
w->data(this);
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on":"off", w->descriptor(), w->flags()
);
return w;
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
);
return w;
}
void Ecore::BusDispatcher::rem_watch( Watch* w )
void Ecore::BusDispatcher::rem_watch(Watch *w)
{
debug_log("ecore: removed watch %p", w);
debug_log("ecore: removed watch %p", w);
delete w;
delete w;
}

View file

@ -39,23 +39,23 @@ using namespace DBus;
*/
Error::Error()
: _int(new InternalError)
: _int(new InternalError)
{}
Error::Error(InternalError &i)
: _int(new InternalError(i))
: _int(new InternalError(i))
{}
Error::Error(const char *name, const char *message)
: _int(new InternalError)
: _int(new InternalError)
{
set(name, message);
set(name, message);
}
Error::Error(Message &m)
: _int(new InternalError)
: _int(new InternalError)
{
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
}
Error::~Error() throw()
@ -64,26 +64,26 @@ Error::~Error() throw()
const char *Error::name() const
{
return _int->error.name;
return _int->error.name;
}
const char *Error::message() const
{
return _int->error.message;
return _int->error.message;
}
bool Error::is_set() const
{
return *(_int);
return *(_int);
}
void Error::set(const char *name, const char *message)
{
dbus_set_error_const(&(_int->error), name, message);
dbus_set_error_const(&(_int->error), name, message);
}
const char *Error::what() const throw()
{
return _int->error.message;
return _int->error.message;
}

View file

@ -43,182 +43,182 @@ using namespace DBus;
using namespace std;
BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
{
DefaultTimeout::enabled(Timeout::enabled());
DefaultTimeout::enabled(Timeout::enabled());
}
void BusTimeout::toggle()
{
debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
DefaultTimeout::enabled(Timeout::enabled());
DefaultTimeout::enabled(Timeout::enabled());
}
BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
{
int flags = POLLHUP | POLLERR;
int flags = POLLHUP | POLLERR;
if (Watch::flags() & DBUS_WATCH_READABLE)
flags |= POLLIN;
if (Watch::flags() & DBUS_WATCH_WRITABLE)
flags |= POLLOUT;
if (Watch::flags() & DBUS_WATCH_READABLE)
flags |= POLLIN;
if (Watch::flags() & DBUS_WATCH_WRITABLE)
flags |= POLLOUT;
DefaultWatch::flags(flags);
DefaultWatch::enabled(Watch::enabled());
DefaultWatch::flags(flags);
DefaultWatch::enabled(Watch::enabled());
}
void BusWatch::toggle()
{
debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
DefaultWatch::enabled(Watch::enabled());
DefaultWatch::enabled(Watch::enabled());
}
BusDispatcher::BusDispatcher() :
_running(false)
_running(false)
{
// pipe to create a new fd used to unlock a dispatcher at any
// pipe to create a new fd used to unlock a dispatcher at any
// moment (used by leave function)
int ret = pipe(_pipe);
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
_fdunlock[0] = _pipe[0];
_fdunlock[1] = _pipe[1];
int ret = pipe(_pipe);
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
_fdunlock[0] = _pipe[0];
_fdunlock[1] = _pipe[1];
}
void BusDispatcher::enter()
{
debug_log("entering dispatcher %p", this);
debug_log("entering dispatcher %p", this);
_running = true;
_running = true;
while (_running)
{
do_iteration();
while (_running)
{
do_iteration();
for (std::list <Pipe*>::iterator p_it = pipe_list.begin ();
p_it != pipe_list.end ();
++p_it)
{
Pipe* read_pipe = *p_it;
for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
p_it != pipe_list.end();
++p_it)
{
Pipe *read_pipe = *p_it;
char buffer[1024]; // TODO: should be max pipe size
unsigned int nbytes = 0;
while (read_pipe->read(buffer, nbytes) > 0)
{
read_pipe->_handler (read_pipe->_data, buffer, nbytes);
{
read_pipe->_handler(read_pipe->_data, buffer, nbytes);
}
}
}
}
}
debug_log("leaving dispatcher %p", this);
debug_log("leaving dispatcher %p", this);
}
void BusDispatcher::leave()
{
_running = false;
int ret = write(_fdunlock[1],"exit",strlen("exit"));
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
close(_fdunlock[1]);
close(_fdunlock[0]);
_running = false;
int ret = write(_fdunlock[1], "exit", strlen("exit"));
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
close(_fdunlock[1]);
close(_fdunlock[0]);
}
Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
{
Pipe *new_pipe = new Pipe (handler, data);
pipe_list.push_back (new_pipe);
Pipe *new_pipe = new Pipe(handler, data);
pipe_list.push_back(new_pipe);
return new_pipe;
return new_pipe;
}
void BusDispatcher::del_pipe (Pipe *pipe)
void BusDispatcher::del_pipe(Pipe *pipe)
{
pipe_list.remove (pipe);
delete pipe;
pipe_list.remove(pipe);
delete pipe;
}
void BusDispatcher::do_iteration()
{
dispatch_pending();
dispatch();
dispatch_pending();
dispatch();
}
Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
{
BusTimeout *bt = new BusTimeout(ti, this);
BusTimeout *bt = new BusTimeout(ti, this);
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
bt->data(bt);
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
bt->data(bt);
debug_log("added timeout %p (%s) (%d millies)",
bt,
((Timeout*)bt)->enabled() ? "on":"off",
((Timeout*)bt)->interval()
);
debug_log("added timeout %p (%s) (%d millies)",
bt,
((Timeout *)bt)->enabled() ? "on" : "off",
((Timeout *)bt)->interval()
);
return bt;
return bt;
}
void BusDispatcher::rem_timeout(Timeout *t)
{
debug_log("removed timeout %p", t);
debug_log("removed timeout %p", t);
delete t;
delete t;
}
Watch *BusDispatcher::add_watch(Watch::Internal *wi)
{
BusWatch *bw = new BusWatch(wi, this);
BusWatch *bw = new BusWatch(wi, this);
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
bw->data(bw);
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
bw->data(bw);
debug_log("added watch %p (%s) fd=%d flags=%d",
bw, ((Watch *)bw)->enabled() ? "on":"off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
debug_log("added watch %p (%s) fd=%d flags=%d",
bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
return bw;
return bw;
}
void BusDispatcher::rem_watch(Watch *w)
{
debug_log("removed watch %p", w);
debug_log("removed watch %p", w);
delete w;
delete w;
}
void BusDispatcher::timeout_expired(DefaultTimeout &et)
{
debug_log("timeout %p expired", &et);
debug_log("timeout %p expired", &et);
BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
timeout->handle();
timeout->handle();
}
void BusDispatcher::watch_ready(DefaultWatch &ew)
{
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
debug_log("watch %p ready, flags=%d state=%d",
watch, ((Watch *)watch)->flags(), watch->state()
);
debug_log("watch %p ready, flags=%d state=%d",
watch, ((Watch *)watch)->flags(), watch->state()
);
int flags = 0;
int flags = 0;
if (watch->state() & POLLIN)
flags |= DBUS_WATCH_READABLE;
if (watch->state() & POLLOUT)
flags |= DBUS_WATCH_WRITABLE;
if (watch->state() & POLLHUP)
flags |= DBUS_WATCH_HANGUP;
if (watch->state() & POLLERR)
flags |= DBUS_WATCH_ERROR;
if (watch->state() & POLLIN)
flags |= DBUS_WATCH_READABLE;
if (watch->state() & POLLOUT)
flags |= DBUS_WATCH_WRITABLE;
if (watch->state() & POLLHUP)
flags |= DBUS_WATCH_HANGUP;
if (watch->state() & POLLERR)
flags |= DBUS_WATCH_ERROR;
watch->handle(flags);
watch->handle(flags);
}

View file

@ -38,225 +38,226 @@ using namespace std;
static double millis(timeval tv)
{
return (tv.tv_sec *1000.0 + tv.tv_usec/1000.0);
return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
}
DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
{
timeval now;
gettimeofday(&now, NULL);
timeval now;
gettimeofday(&now, NULL);
_expiration = millis(now) + interval;
_expiration = millis(now) + interval;
_disp->_mutex_t.lock();
_disp->_timeouts.push_back(this);
_disp->_mutex_t.unlock();
_disp->_mutex_t.lock();
_disp->_timeouts.push_back(this);
_disp->_mutex_t.unlock();
}
DefaultTimeout::~DefaultTimeout()
{
_disp->_mutex_t.lock();
_disp->_timeouts.remove(this);
_disp->_mutex_t.unlock();
_disp->_mutex_t.lock();
_disp->_timeouts.remove(this);
_disp->_mutex_t.unlock();
}
DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
{
_disp->_mutex_w.lock();
_disp->_watches.push_back(this);
_disp->_mutex_w.unlock();
_disp->_mutex_w.lock();
_disp->_watches.push_back(this);
_disp->_mutex_w.unlock();
}
DefaultWatch::~DefaultWatch()
{
_disp->_mutex_w.lock();
_disp->_watches.remove(this);
_disp->_mutex_w.unlock();
_disp->_mutex_w.lock();
_disp->_watches.remove(this);
_disp->_mutex_w.unlock();
}
DefaultMutex::DefaultMutex()
{
pthread_mutex_init(&_mutex, NULL);
pthread_mutex_init(&_mutex, NULL);
}
DefaultMutex::DefaultMutex(bool recursive)
{
if (recursive)
{
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_mutex = recmutex;
}
else
{
pthread_mutex_init(&_mutex, NULL);
}
if (recursive)
{
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_mutex = recmutex;
}
else
{
pthread_mutex_init(&_mutex, NULL);
}
}
DefaultMutex::~DefaultMutex()
{
pthread_mutex_destroy(&_mutex);
pthread_mutex_destroy(&_mutex);
}
void DefaultMutex::lock()
{
pthread_mutex_lock(&_mutex);
pthread_mutex_lock(&_mutex);
}
void DefaultMutex::unlock()
{
pthread_mutex_unlock(&_mutex);
pthread_mutex_unlock(&_mutex);
}
DefaultMainLoop::DefaultMainLoop() :
_mutex_w(true)
_mutex_w(true)
{
}
DefaultMainLoop::~DefaultMainLoop()
{
_mutex_w.lock();
_mutex_w.lock();
DefaultWatches::iterator wi = _watches.begin();
while (wi != _watches.end())
{
DefaultWatches::iterator wmp = wi;
++wmp;
_mutex_w.unlock();
delete (*wi);
_mutex_w.lock();
wi = wmp;
}
_mutex_w.unlock();
DefaultWatches::iterator wi = _watches.begin();
while (wi != _watches.end())
{
DefaultWatches::iterator wmp = wi;
++wmp;
_mutex_w.unlock();
delete(*wi);
_mutex_w.lock();
wi = wmp;
}
_mutex_w.unlock();
_mutex_t.lock();
_mutex_t.lock();
DefaultTimeouts::iterator ti = _timeouts.begin();
while (ti != _timeouts.end())
{
DefaultTimeouts::iterator tmp = ti;
++tmp;
_mutex_t.unlock();
delete (*ti);
_mutex_t.lock();
ti = tmp;
}
_mutex_t.unlock();
DefaultTimeouts::iterator ti = _timeouts.begin();
while (ti != _timeouts.end())
{
DefaultTimeouts::iterator tmp = ti;
++tmp;
_mutex_t.unlock();
delete(*ti);
_mutex_t.lock();
ti = tmp;
}
_mutex_t.unlock();
}
void DefaultMainLoop::dispatch()
{
_mutex_w.lock();
_mutex_w.lock();
int nfd = _watches.size();
int nfd = _watches.size();
if(_fdunlock)
{
nfd=nfd+2;
}
if (_fdunlock)
{
nfd = nfd + 2;
}
pollfd fds[nfd];
pollfd fds[nfd];
DefaultWatches::iterator wi = _watches.begin();
DefaultWatches::iterator wi = _watches.begin();
for (nfd = 0; wi != _watches.end(); ++wi)
{
if ((*wi)->enabled())
{
fds[nfd].fd = (*wi)->descriptor();
fds[nfd].events = (*wi)->flags();
fds[nfd].revents = 0;
for (nfd = 0; wi != _watches.end(); ++wi)
{
if ((*wi)->enabled())
{
fds[nfd].fd = (*wi)->descriptor();
fds[nfd].events = (*wi)->flags();
fds[nfd].revents = 0;
++nfd;
}
}
++nfd;
}
}
if(_fdunlock){
fds[nfd].fd = _fdunlock[0];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
nfd++;
fds[nfd].fd = _fdunlock[1];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
}
if (_fdunlock)
{
fds[nfd].fd = _fdunlock[0];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
_mutex_w.unlock();
nfd++;
fds[nfd].fd = _fdunlock[1];
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
fds[nfd].revents = 0;
}
int wait_min = 10000;
_mutex_w.unlock();
DefaultTimeouts::iterator ti;
int wait_min = 10000;
_mutex_t.lock();
DefaultTimeouts::iterator ti;
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
{
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
wait_min = (*ti)->interval();
}
_mutex_t.lock();
_mutex_t.unlock();
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
{
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
wait_min = (*ti)->interval();
}
poll(fds, nfd, wait_min);
_mutex_t.unlock();
timeval now;
gettimeofday(&now, NULL);
poll(fds, nfd, wait_min);
double now_millis = millis(now);
timeval now;
gettimeofday(&now, NULL);
_mutex_t.lock();
double now_millis = millis(now);
ti = _timeouts.begin();
_mutex_t.lock();
while (ti != _timeouts.end())
{
DefaultTimeouts::iterator tmp = ti;
++tmp;
ti = _timeouts.begin();
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
{
(*ti)->expired(*(*ti));
while (ti != _timeouts.end())
{
DefaultTimeouts::iterator tmp = ti;
++tmp;
if ((*ti)->_repeat)
{
(*ti)->_expiration = now_millis + (*ti)->_interval;
}
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
{
(*ti)->expired(*(*ti));
}
if ((*ti)->_repeat)
{
(*ti)->_expiration = now_millis + (*ti)->_interval;
}
ti = tmp;
}
}
_mutex_t.unlock();
ti = tmp;
}
_mutex_w.lock();
_mutex_t.unlock();
for (int j = 0; j < nfd; ++j)
{
DefaultWatches::iterator wi;
_mutex_w.lock();
for (wi = _watches.begin(); wi != _watches.end();)
{
DefaultWatches::iterator tmp = wi;
++tmp;
for (int j = 0; j < nfd; ++j)
{
DefaultWatches::iterator wi;
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
{
if (fds[j].revents)
{
(*wi)->_state = fds[j].revents;
for (wi = _watches.begin(); wi != _watches.end();)
{
DefaultWatches::iterator tmp = wi;
++tmp;
(*wi)->ready(*(*wi));
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
{
if (fds[j].revents)
{
(*wi)->_state = fds[j].revents;
fds[j].revents = 0;
}
}
(*wi)->ready(*(*wi));
wi = tmp;
}
}
_mutex_w.unlock();
fds[j].revents = 0;
}
}
wi = tmp;
}
}
_mutex_w.unlock();
}

View file

@ -31,169 +31,170 @@
using namespace DBus;
Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
{
if (Timeout::enabled())
_enable();
if (Timeout::enabled())
_enable();
}
Glib::BusTimeout::~BusTimeout()
{
_disable();
_disable();
}
void Glib::BusTimeout::toggle()
{
debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
if (Timeout::enabled()) _enable();
else _disable();
if (Timeout::enabled()) _enable();
else _disable();
}
gboolean Glib::BusTimeout::timeout_handler(gpointer data)
{
Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
t->handle();
t->handle();
return TRUE;
return TRUE;
}
void Glib::BusTimeout::_enable()
{
if (_source)
_disable(); // be sane
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);
g_source_attach(_source, _ctx);
_source = g_timeout_source_new(Timeout::interval());
g_source_set_priority(_source, _priority);
g_source_set_callback(_source, timeout_handler, this, NULL);
g_source_attach(_source, _ctx);
}
void Glib::BusTimeout::_disable()
{
if (_source)
{
g_source_destroy(_source);
_source = NULL;
}
if (_source)
{
g_source_destroy(_source);
_source = NULL;
}
}
struct BusSource
{
GSource source;
GPollFD poll;
GSource source;
GPollFD poll;
};
static gboolean watch_prepare(GSource *source, gint *timeout)
{
debug_log("glib: watch_prepare");
debug_log("glib: watch_prepare");
*timeout = -1;
return FALSE;
*timeout = -1;
return FALSE;
}
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;
BusSource *io = (BusSource *)source;
return io->poll.revents ? TRUE : FALSE;
}
static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data)
{
debug_log("glib: watch_dispatch");
debug_log("glib: watch_dispatch");
gboolean cb = callback(data);
return cb;
gboolean cb = callback(data);
return cb;
}
static GSourceFuncs watch_funcs = {
watch_prepare,
watch_check,
watch_dispatch,
NULL
static GSourceFuncs watch_funcs =
{
watch_prepare,
watch_check,
watch_dispatch,
NULL
};
Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
{
if (Watch::enabled())
_enable();
if (Watch::enabled())
_enable();
}
Glib::BusWatch::~BusWatch()
{
_disable();
_disable();
}
void Glib::BusWatch::toggle()
{
debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
if (Watch::enabled()) _enable();
else _disable();
if (Watch::enabled()) _enable();
else _disable();
}
gboolean Glib::BusWatch::watch_handler(gpointer data)
{
Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
BusSource *io = (BusSource *)(w->_source);
BusSource *io = (BusSource *)(w->_source);
int flags = 0;
if (io->poll.revents &G_IO_IN)
flags |= DBUS_WATCH_READABLE;
if (io->poll.revents &G_IO_OUT)
flags |= DBUS_WATCH_WRITABLE;
if (io->poll.revents &G_IO_ERR)
flags |= DBUS_WATCH_ERROR;
if (io->poll.revents &G_IO_HUP)
flags |= DBUS_WATCH_HANGUP;
int flags = 0;
if (io->poll.revents & G_IO_IN)
flags |= DBUS_WATCH_READABLE;
if (io->poll.revents & G_IO_OUT)
flags |= DBUS_WATCH_WRITABLE;
if (io->poll.revents & G_IO_ERR)
flags |= DBUS_WATCH_ERROR;
if (io->poll.revents & G_IO_HUP)
flags |= DBUS_WATCH_HANGUP;
w->handle(flags);
w->handle(flags);
return TRUE;
return TRUE;
}
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);
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);
int flags = Watch::flags();
int condition = 0;
int flags = Watch::flags();
int condition = 0;
if (flags &DBUS_WATCH_READABLE)
condition |= G_IO_IN;
if (flags &DBUS_WATCH_WRITABLE)
condition |= G_IO_OUT;
if (flags &DBUS_WATCH_ERROR)
condition |= G_IO_ERR;
if (flags &DBUS_WATCH_HANGUP)
condition |= G_IO_HUP;
if (flags & DBUS_WATCH_READABLE)
condition |= G_IO_IN;
if (flags & DBUS_WATCH_WRITABLE)
condition |= G_IO_OUT;
if (flags & DBUS_WATCH_ERROR)
condition |= G_IO_ERR;
if (flags & DBUS_WATCH_HANGUP)
condition |= G_IO_HUP;
GPollFD *poll = &(((BusSource *)_source)->poll);
poll->fd = Watch::descriptor();
poll->events = condition;
poll->revents = 0;
GPollFD *poll = &(((BusSource *)_source)->poll);
poll->fd = Watch::descriptor();
poll->events = condition;
poll->revents = 0;
g_source_add_poll(_source, poll);
g_source_attach(_source, _ctx);
g_source_add_poll(_source, poll);
g_source_attach(_source, _ctx);
}
void Glib::BusWatch::_disable()
{
if (!_source)
return;
GPollFD *poll = &(((BusSource *)_source)->poll);
g_source_remove_poll(_source, poll);
g_source_destroy(_source);
_source = NULL;
if (!_source)
return;
GPollFD *poll = &(((BusSource *)_source)->poll);
g_source_remove_poll(_source, poll);
g_source_destroy(_source);
_source = NULL;
}
/*
@ -203,23 +204,23 @@ void Glib::BusWatch::_disable()
*/
struct DispatcherSource
{
GSource source;
Dispatcher *dispatcher;
GSource source;
Dispatcher *dispatcher;
};
static gboolean dispatcher_prepare(GSource *source, gint *timeout)
{
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
*timeout = -1;
Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
return dispatcher->has_something_to_dispatch()? TRUE:FALSE;
*timeout = -1;
return dispatcher->has_something_to_dispatch() ? TRUE : FALSE;
}
static gboolean dispatcher_check(GSource *source)
{
return FALSE;
return FALSE;
}
static gboolean
@ -227,88 +228,89 @@ dispatcher_dispatch(GSource *source,
GSourceFunc callback,
gpointer user_data)
{
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
dispatcher->dispatch_pending();
return TRUE;
dispatcher->dispatch_pending();
return TRUE;
}
static const GSourceFuncs dispatcher_funcs = {
dispatcher_prepare,
dispatcher_check,
dispatcher_dispatch,
NULL
static const GSourceFuncs dispatcher_funcs =
{
dispatcher_prepare,
dispatcher_check,
dispatcher_dispatch,
NULL
};
Glib::BusDispatcher::BusDispatcher()
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
{
}
Glib::BusDispatcher::~BusDispatcher()
{
if (_source)
{
GSource *temp = _source;
_source = NULL;
if (_source)
{
GSource *temp = _source;
_source = NULL;
g_source_destroy (temp);
g_source_unref (temp);
}
g_source_destroy(temp);
g_source_unref(temp);
}
if (_ctx)
g_main_context_unref(_ctx);
if (_ctx)
g_main_context_unref(_ctx);
}
void Glib::BusDispatcher::attach(GMainContext *ctx)
{
g_assert(_ctx == NULL); // just to be sane
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));
_ctx = ctx ? ctx : g_main_context_default();
g_main_context_ref(_ctx);
((DispatcherSource*)_source)->dispatcher = this;
g_source_attach (_source, _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 *t = new Glib::BusTimeout(wi, _ctx, _priority);
Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority);
debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on":"off");
debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
return t;
return t;
}
void Glib::BusDispatcher::rem_timeout(Timeout *t)
{
debug_log("glib: removed timeout %p", t);
debug_log("glib: removed timeout %p", t);
delete t;
delete t;
}
Watch *Glib::BusDispatcher::add_watch(Watch::Internal *wi)
{
Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
debug_log("glib: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on":"off", w->descriptor(), w->flags()
);
return w;
debug_log("glib: added watch %p (%s) fd=%d flags=%d",
w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
);
return w;
}
void Glib::BusDispatcher::rem_watch(Watch *w)
{
debug_log("glib: removed watch %p", w);
debug_log("glib: removed watch %p", w);
delete w;
delete w;
}
void Glib::BusDispatcher::set_priority(int priority)
{
_priority = priority;
_priority = priority;
}

View file

@ -33,7 +33,7 @@
using namespace DBus;
Interface::Interface(const std::string &name)
: _name(name)
: _name(name)
{}
Interface::~Interface()
@ -41,129 +41,129 @@ Interface::~Interface()
InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name)
{
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL;
return ii != _interfaces.end() ? ii->second : NULL;
}
InterfaceAdaptor::InterfaceAdaptor(const std::string &name)
: Interface(name)
: Interface(name)
{
debug_log("adding interface %s", name.c_str());
debug_log("adding interface %s", name.c_str());
_interfaces[name] = this;
_interfaces[name] = this;
}
Message InterfaceAdaptor::dispatch_method(const CallMessage &msg)
{
const char *name = msg.member();
const char *name = msg.member();
MethodTable::iterator mi = _methods.find(name);
if (mi != _methods.end())
{
return mi->second.call(msg);
}
else
{
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
}
MethodTable::iterator mi = _methods.find(name);
if (mi != _methods.end())
{
return mi->second.call(msg);
}
else
{
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
}
}
void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
{
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
if (sig2.interface() == NULL)
sig2.interface(name().c_str());
if (sig2.interface() == NULL)
sig2.interface(name().c_str());
_emit_signal(sig2);
_emit_signal(sig2);
}
Variant *InterfaceAdaptor::get_property(const std::string &name)
{
PropertyTable::iterator pti = _properties.find(name);
PropertyTable::iterator pti = _properties.find(name);
if (pti != _properties.end())
{
if (!pti->second.read)
throw ErrorAccessDenied("property is not readable");
if (pti != _properties.end())
{
if (!pti->second.read)
throw ErrorAccessDenied("property is not readable");
return &(pti->second.value);
}
return NULL;
return &(pti->second.value);
}
return NULL;
}
void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
{
PropertyTable::iterator pti = _properties.find(name);
PropertyTable::iterator pti = _properties.find(name);
if (pti != _properties.end())
{
if (!pti->second.write)
throw ErrorAccessDenied("property is not writeable");
if (pti != _properties.end())
{
if (!pti->second.write)
throw ErrorAccessDenied("property is not writeable");
Signature sig = value.signature();
Signature sig = value.signature();
if (pti->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type");
if (pti->second.sig != sig)
throw ErrorInvalidSignature("property expects a different type");
pti->second.value = value;
return;
}
throw ErrorFailed("requested property not found");
pti->second.value = value;
return;
}
throw ErrorFailed("requested property not found");
}
InterfaceProxy *ProxyBase::find_interface(const std::string &name)
{
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
return ii != _interfaces.end() ? ii->second : NULL;
return ii != _interfaces.end() ? ii->second : NULL;
}
InterfaceProxy::InterfaceProxy(const std::string &name)
: Interface(name)
: Interface(name)
{
debug_log("adding interface %s", name.c_str());
debug_log("adding interface %s", name.c_str());
_interfaces[name] = this;
_interfaces[name] = this;
}
bool InterfaceProxy::dispatch_signal(const SignalMessage &msg)
{
const char *name = msg.member();
const char *name = msg.member();
SignalTable::iterator si = _signals.find(name);
if (si != _signals.end())
{
si->second.call(msg);
// Here we always return false because there might be
// another InterfaceProxy listening for the same signal.
// This way we instruct libdbus-1 to go on dispatching
// the signal.
return false;
}
else
{
return false;
}
SignalTable::iterator si = _signals.find(name);
if (si != _signals.end())
{
si->second.call(msg);
// Here we always return false because there might be
// another InterfaceProxy listening for the same signal.
// This way we instruct libdbus-1 to go on dispatching
// the signal.
return false;
}
else
{
return false;
}
}
Message InterfaceProxy::invoke_method(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL)
call2.interface(name().c_str());
if (call.interface() == NULL)
call2.interface(name().c_str());
return _invoke_method(call2);
return _invoke_method(call2);
}
bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
{
CallMessage &call2 = const_cast<CallMessage &>(call);
CallMessage &call2 = const_cast<CallMessage &>(call);
if (call.interface() == NULL)
call2.interface(name().c_str());
if (call.interface() == NULL)
call2.interface(name().c_str());
return _invoke_method_noreply(call2);
return _invoke_method_noreply(call2);
}

View file

@ -33,43 +33,44 @@
#include <dbus/dbus.h>
namespace DBus {
namespace DBus
{
struct DXXAPI InternalError
{
DBusError error;
DBusError error;
InternalError()
{
dbus_error_init(&error);
}
InternalError()
{
dbus_error_init(&error);
}
explicit InternalError(DBusError *e)
{
dbus_error_init(&error);
dbus_move_error(e, &error);
}
explicit InternalError(DBusError *e)
{
dbus_error_init(&error);
dbus_move_error(e, &error);
}
InternalError(const InternalError &ie)
{
dbus_error_init(&error);
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
}
~InternalError()
{
dbus_error_free(&error);
}
InternalError(const InternalError &ie)
{
dbus_error_init(&error);
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
}
operator DBusError *()
{
return &error;
}
~InternalError()
{
dbus_error_free(&error);
}
operator bool()
{
return dbus_error_is_set(&error);
}
operator DBusError *()
{
return &error;
}
operator bool()
{
return dbus_error_is_set(&error);
}
};
} /* namespace DBus */

View file

@ -38,156 +38,156 @@ using namespace DBus;
static const char *introspectable_name = "org.freedesktop.DBus.Introspectable";
IntrospectableAdaptor::IntrospectableAdaptor()
: InterfaceAdaptor(introspectable_name)
: InterfaceAdaptor(introspectable_name)
{
register_method(IntrospectableAdaptor, Introspect, Introspect);
register_method(IntrospectableAdaptor, Introspect, Introspect);
}
Message IntrospectableAdaptor::Introspect(const CallMessage &call)
{
debug_log("requested introspection data");
debug_log("requested introspection data");
std::ostringstream xml;
std::ostringstream xml;
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
const std::string path = object()->path();
const std::string path = object()->path();
xml << "<node name=\"" << path << "\">";
xml << "<node name=\"" << path << "\">";
InterfaceAdaptorTable::const_iterator iti;
InterfaceAdaptorTable::const_iterator iti;
for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
{
debug_log("introspecting interface %s", iti->first.c_str());
for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
{
debug_log("introspecting interface %s", iti->first.c_str());
IntrospectedInterface *const intro = iti->second->introspect();
if (intro)
{
xml << "\n\t<interface name=\"" << intro->name << "\">";
IntrospectedInterface *const intro = iti->second->introspect();
if (intro)
{
xml << "\n\t<interface name=\"" << intro->name << "\">";
for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
{
std::string access;
for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
{
std::string access;
if (p->read) access += "read";
if (p->write) access += "write";
if (p->read) access += "read";
if (p->write) access += "write";
xml << "\n\t\t<property name=\"" << p->name << "\""
<< " type=\"" << p->type << "\""
<< " access=\"" << access << "\"/>";
}
xml << "\n\t\t<property name=\"" << p->name << "\""
<< " type=\"" << p->type << "\""
<< " access=\"" << access << "\"/>";
}
for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
{
xml << "\n\t\t<method name=\"" << m->name << "\">";
for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
{
xml << "\n\t\t<method name=\"" << m->name << "\">";
for (const IntrospectedArgument *a = m->args; a->type; ++a)
{
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
<< " type=\"" << a->type << "\"";
for (const IntrospectedArgument *a = m->args; a->type; ++a)
{
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
<< " type=\"" << a->type << "\"";
if (a->name) xml << " name=\"" << a->name << "\"";
if (a->name) xml << " name=\"" << a->name << "\"";
xml << "/>";
}
xml << "/>";
}
xml << "\n\t\t</method>";
}
xml << "\n\t\t</method>";
}
for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
{
xml << "\n\t\t<signal name=\"" << m->name << "\">";
for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
{
xml << "\n\t\t<signal name=\"" << m->name << "\">";
for (const IntrospectedArgument *a = m->args; a->type; ++a)
{
xml << "<arg type=\"" << a->type << "\"";
for (const IntrospectedArgument *a = m->args; a->type; ++a)
{
xml << "<arg type=\"" << a->type << "\"";
if (a->name) xml << " name=\"" << a->name << "\"";
if (a->name) xml << " name=\"" << a->name << "\"";
xml << "/>";
}
xml << "\n\t\t</signal>";
}
xml << "/>";
}
xml << "\n\t\t</signal>";
}
xml << "\n\t</interface>";
}
}
xml << "\n\t</interface>";
}
}
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
ObjectPathList::const_iterator oni;
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
ObjectPathList::const_iterator oni;
for (oni = nodes.begin(); oni != nodes.end(); ++oni)
{
xml << "\n\t<node name=\"" << (*oni) << "\"/>";
}
for (oni = nodes.begin(); oni != nodes.end(); ++oni)
{
xml << "\n\t<node name=\"" << (*oni) << "\"/>";
}
/* broken
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
/* broken
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
ObjectAdaptorPList::const_iterator oci;
ObjectAdaptorPList::const_iterator oci;
for (oci = children.begin(); oci != children.end(); ++oci)
{
std::string name = (*oci)->path().substr(path.length()+1);
name.substr(name.find('/'));
for (oci = children.begin(); oci != children.end(); ++oci)
{
std::string name = (*oci)->path().substr(path.length()+1);
name.substr(name.find('/'));
xml << "<node name=\"" << name << "\"/>";
}
*/
xml << "<node name=\"" << name << "\"/>";
}
*/
xml << "\n</node>";
xml << "\n</node>";
ReturnMessage reply(call);
MessageIter wi = reply.writer();
wi.append_string(xml.str().c_str());
return reply;
ReturnMessage reply(call);
MessageIter wi = reply.writer();
wi.append_string(xml.str().c_str());
return reply;
}
IntrospectedInterface * IntrospectableAdaptor::introspect() const
IntrospectedInterface *IntrospectableAdaptor::introspect() const
{
static IntrospectedArgument Introspect_args[] =
{
{ "data", "s", false },
{ 0, 0, 0 }
};
static IntrospectedMethod Introspectable_methods[] =
{
{ "Introspect", Introspect_args },
{ 0, 0 }
};
static IntrospectedMethod Introspectable_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Introspectable_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Introspectable_interface =
{
introspectable_name,
Introspectable_methods,
Introspectable_signals,
Introspectable_properties
};
return &Introspectable_interface;
static IntrospectedArgument Introspect_args[] =
{
{ "data", "s", false },
{ 0, 0, 0 }
};
static IntrospectedMethod Introspectable_methods[] =
{
{ "Introspect", Introspect_args },
{ 0, 0 }
};
static IntrospectedMethod Introspectable_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Introspectable_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Introspectable_interface =
{
introspectable_name,
Introspectable_methods,
Introspectable_signals,
Introspectable_properties
};
return &Introspectable_interface;
}
IntrospectableProxy::IntrospectableProxy()
: InterfaceProxy(introspectable_name)
: InterfaceProxy(introspectable_name)
{}
std::string IntrospectableProxy::Introspect()
{
DBus::CallMessage call;
DBus::CallMessage call;
call.member("Introspect");
call.member("Introspect");
DBus::Message ret = invoke_method(call);
DBus::Message ret = invoke_method(call);
DBus::MessageIter ri = ret.reader();
const char *str = ri.get_string();
DBus::MessageIter ri = ret.reader();
const char *str = ri.get_string();
return str;
return str;
}

View file

@ -40,475 +40,475 @@ using namespace DBus;
int MessageIter::type()
{
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
}
bool MessageIter::at_end()
{
return type() == DBUS_TYPE_INVALID;
return type() == DBUS_TYPE_INVALID;
}
bool MessageIter::has_next()
{
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
}
MessageIter &MessageIter::operator ++()
{
dbus_message_iter_next((DBusMessageIter *)&_iter);
return (*this);
dbus_message_iter_next((DBusMessageIter *)&_iter);
return (*this);
}
MessageIter MessageIter::operator ++(int)
{
MessageIter copy(*this);
++(*this);
return copy;
MessageIter copy(*this);
++(*this);
return copy;
}
bool MessageIter::append_basic(int type_id, void *value)
{
return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
}
void MessageIter::get_basic(int type_id, void *ptr)
{
if (type() != type_id)
throw ErrorInvalidArgs("type mismatch");
if (type() != type_id)
throw ErrorInvalidArgs("type mismatch");
dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
}
bool MessageIter::append_byte(unsigned char b)
{
return append_basic(DBUS_TYPE_BYTE, &b);
return append_basic(DBUS_TYPE_BYTE, &b);
}
unsigned char MessageIter::get_byte()
{
unsigned char b;
get_basic(DBUS_TYPE_BYTE, &b);
return b;
{
unsigned char b;
get_basic(DBUS_TYPE_BYTE, &b);
return b;
}
bool MessageIter::append_bool(bool b)
{
dbus_bool_t db = b;
return append_basic(DBUS_TYPE_BOOLEAN, &db);
dbus_bool_t db = b;
return append_basic(DBUS_TYPE_BOOLEAN, &db);
}
bool MessageIter::get_bool()
bool MessageIter::get_bool()
{
dbus_bool_t db;
get_basic(DBUS_TYPE_BOOLEAN, &db);
return (bool)db;
dbus_bool_t db;
get_basic(DBUS_TYPE_BOOLEAN, &db);
return (bool)db;
}
bool MessageIter::append_int16(signed short i)
{
return append_basic(DBUS_TYPE_INT16, &i);
return append_basic(DBUS_TYPE_INT16, &i);
}
signed short MessageIter::get_int16()
{
signed short i;
get_basic(DBUS_TYPE_INT16, &i);
return i;
{
signed short i;
get_basic(DBUS_TYPE_INT16, &i);
return i;
}
bool MessageIter::append_uint16(unsigned short u)
{
return append_basic(DBUS_TYPE_UINT16, &u);
return append_basic(DBUS_TYPE_UINT16, &u);
}
unsigned short MessageIter::get_uint16()
{
unsigned short u;
get_basic(DBUS_TYPE_UINT16, &u);
return u;
{
unsigned short u;
get_basic(DBUS_TYPE_UINT16, &u);
return u;
}
bool MessageIter::append_int32(signed int i)
{
return append_basic(DBUS_TYPE_INT32, &i);
return append_basic(DBUS_TYPE_INT32, &i);
}
signed int MessageIter::get_int32()
{
signed int i;
get_basic(DBUS_TYPE_INT32, &i);
return i;
{
signed int i;
get_basic(DBUS_TYPE_INT32, &i);
return i;
}
bool MessageIter::append_uint32(unsigned int u)
{
return append_basic(DBUS_TYPE_UINT32, &u);
return append_basic(DBUS_TYPE_UINT32, &u);
}
unsigned int MessageIter::get_uint32()
{
unsigned int u;
get_basic(DBUS_TYPE_UINT32, &u);
return u;
{
unsigned int u;
get_basic(DBUS_TYPE_UINT32, &u);
return u;
}
signed long long MessageIter::get_int64()
{
signed long long i;
get_basic(DBUS_TYPE_INT64, &i);
return i;
signed long long i;
get_basic(DBUS_TYPE_INT64, &i);
return i;
}
bool MessageIter::append_int64(signed long long i)
{
return append_basic(DBUS_TYPE_INT64, &i);
return append_basic(DBUS_TYPE_INT64, &i);
}
unsigned long long MessageIter::get_uint64()
{
unsigned long long u;
get_basic(DBUS_TYPE_UINT64, &u);
return u;
unsigned long long u;
get_basic(DBUS_TYPE_UINT64, &u);
return u;
}
bool MessageIter::append_uint64(unsigned long long u)
{
return append_basic(DBUS_TYPE_UINT64, &u);
return append_basic(DBUS_TYPE_UINT64, &u);
}
double MessageIter::get_double()
{
double d;
get_basic(DBUS_TYPE_DOUBLE, &d);
return d;
double d;
get_basic(DBUS_TYPE_DOUBLE, &d);
return d;
}
bool MessageIter::append_double(double d)
{
return append_basic(DBUS_TYPE_DOUBLE, &d);
return append_basic(DBUS_TYPE_DOUBLE, &d);
}
bool MessageIter::append_string(const char *chars)
{
return append_basic(DBUS_TYPE_STRING, &chars);
return append_basic(DBUS_TYPE_STRING, &chars);
}
const char *MessageIter::get_string()
{
char *chars;
get_basic(DBUS_TYPE_STRING, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_STRING, &chars);
return chars;
}
bool MessageIter::append_path(const char *chars)
{
return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
}
const char *MessageIter::get_path()
{
char *chars;
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
return chars;
}
bool MessageIter::append_signature(const char *chars)
{
return append_basic(DBUS_TYPE_SIGNATURE, &chars);
return append_basic(DBUS_TYPE_SIGNATURE, &chars);
}
const char *MessageIter::get_signature()
{
char *chars;
get_basic(DBUS_TYPE_SIGNATURE, &chars);
return chars;
char *chars;
get_basic(DBUS_TYPE_SIGNATURE, &chars);
return chars;
}
MessageIter MessageIter::recurse()
MessageIter MessageIter::recurse()
{
MessageIter iter(msg());
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(msg());
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
return iter;
}
char *MessageIter::signature() const
{
return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
}
bool MessageIter::append_array(char type, const void *ptr, size_t length)
{
return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
}
int MessageIter::array_type()
{
return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
}
int MessageIter::get_array(void *ptr)
{
int length;
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
return length;
int length;
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
return length;
}
bool MessageIter::is_array()
{
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
}
bool MessageIter::is_dict()
{
return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
}
MessageIter MessageIter::new_array(const char *sig)
{
MessageIter arr(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *)&(arr._iter)
);
return arr;
MessageIter arr(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
);
return arr;
}
MessageIter MessageIter::new_variant(const char *sig)
{
MessageIter var(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *)&(var._iter)
);
return var;
MessageIter var(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
);
return var;
}
MessageIter MessageIter::new_struct()
{
MessageIter stu(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *)&(stu._iter)
);
return stu;
MessageIter stu(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
);
return stu;
}
MessageIter MessageIter::new_dict_entry()
{
MessageIter ent(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *)&(ent._iter)
);
return ent;
MessageIter ent(msg());
dbus_message_iter_open_container(
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
);
return ent;
}
void MessageIter::close_container(MessageIter &container)
{
dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *)&(container._iter));
dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *) & (container._iter));
}
static bool is_basic_type(int typecode)
{
switch (typecode)
{
case 'y':
case 'b':
case 'n':
case 'q':
case 'i':
case 'u':
case 'x':
case 't':
case 'd':
case 's':
case 'o':
case 'g':
return true;
default:
return false;
}
switch (typecode)
{
case 'y':
case 'b':
case 'n':
case 'q':
case 'i':
case 'u':
case 'x':
case 't':
case 'd':
case 's':
case 'o':
case 'g':
return true;
default:
return false;
}
}
void MessageIter::copy_data(MessageIter &to)
{
for (MessageIter &from = *this; !from.at_end(); ++from)
{
if (is_basic_type(from.type()))
{
debug_log("copying basic type: %c", from.type());
for (MessageIter &from = *this; !from.at_end(); ++from)
{
if (is_basic_type(from.type()))
{
debug_log("copying basic type: %c", from.type());
unsigned char value[8];
from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value);
}
else
{
MessageIter from_container = from.recurse();
char *sig = from_container.signature();
unsigned char value[8];
from.get_basic(from.type(), &value);
to.append_basic(from.type(), &value);
}
else
{
MessageIter from_container = from.recurse();
char *sig = from_container.signature();
debug_log("copying compound type: %c[%s]", from.type(), sig);
debug_log("copying compound type: %c[%s]", from.type(), sig);
MessageIter to_container (to.msg());
dbus_message_iter_open_container
(
(DBusMessageIter *)&(to._iter),
from.type(),
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
(DBusMessageIter *)&(to_container._iter)
);
MessageIter to_container(to.msg());
dbus_message_iter_open_container
(
(DBusMessageIter *) & (to._iter),
from.type(),
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
(DBusMessageIter *) & (to_container._iter)
);
from_container.copy_data(to_container);
to.close_container(to_container);
free(sig);
}
}
from_container.copy_data(to_container);
to.close_container(to_container);
free(sig);
}
}
}
/*
*/
Message::Message()
: _pvt(new Private)
: _pvt(new Private)
{
}
Message::Message(Message::Private *p, bool incref)
: _pvt(p)
: _pvt(p)
{
if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
}
Message::Message(const Message &m)
: _pvt(m._pvt)
: _pvt(m._pvt)
{
dbus_message_ref(_pvt->msg);
dbus_message_ref(_pvt->msg);
}
Message::~Message()
{
dbus_message_unref(_pvt->msg);
dbus_message_unref(_pvt->msg);
}
Message &Message::operator = (const Message &m)
{
if (&m != this)
{
dbus_message_unref(_pvt->msg);
_pvt = m._pvt;
dbus_message_ref(_pvt->msg);
}
return *this;
if (&m != this)
{
dbus_message_unref(_pvt->msg);
_pvt = m._pvt;
dbus_message_ref(_pvt->msg);
}
return *this;
}
Message Message::copy()
{
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
return Message(pvt);
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
return Message(pvt);
}
bool Message::append(int first_type, ...)
{
va_list vl;
va_start(vl, first_type);
va_list vl;
va_start(vl, first_type);
bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
va_end(vl);
return b;
va_end(vl);
return b;
}
void Message::terminate()
{
dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
}
int Message::type() const
{
return dbus_message_get_type(_pvt->msg);
return dbus_message_get_type(_pvt->msg);
}
int Message::serial() const
{
return dbus_message_get_serial(_pvt->msg);
return dbus_message_get_serial(_pvt->msg);
}
int Message::reply_serial() const
{
return dbus_message_get_reply_serial(_pvt->msg);
return dbus_message_get_reply_serial(_pvt->msg);
}
bool Message::reply_serial(int s)
{
return dbus_message_set_reply_serial(_pvt->msg, s);
return dbus_message_set_reply_serial(_pvt->msg, s);
}
const char *Message::sender() const
{
return dbus_message_get_sender(_pvt->msg);
return dbus_message_get_sender(_pvt->msg);
}
bool Message::sender(const char *s)
{
return dbus_message_set_sender(_pvt->msg, s);
return dbus_message_set_sender(_pvt->msg, s);
}
const char *Message::destination() const
{
return dbus_message_get_destination(_pvt->msg);
return dbus_message_get_destination(_pvt->msg);
}
bool Message::destination(const char *s)
{
return dbus_message_set_destination(_pvt->msg, s);
return dbus_message_set_destination(_pvt->msg, s);
}
bool Message::is_error() const
{
return type() == DBUS_MESSAGE_TYPE_ERROR;
return type() == DBUS_MESSAGE_TYPE_ERROR;
}
bool Message::is_signal(const char *interface, const char *member) const
{
return dbus_message_is_signal(_pvt->msg, interface, member);
return dbus_message_is_signal(_pvt->msg, interface, member);
}
MessageIter Message::writer()
{
MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(*this);
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter;
}
MessageIter Message::reader() const
{
MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *)&(iter._iter));
return iter;
MessageIter iter(const_cast<Message &>(*this));
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
return iter;
}
/*
/*
*/
ErrorMessage::ErrorMessage()
{
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
}
ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
{
_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
}
bool ErrorMessage::operator == (const ErrorMessage &m) const
{
return dbus_message_is_error(_pvt->msg, m.name());
return dbus_message_is_error(_pvt->msg, m.name());
}
const char *ErrorMessage::name() const
{
return dbus_message_get_error_name(_pvt->msg);
return dbus_message_get_error_name(_pvt->msg);
}
bool ErrorMessage::name(const char *n)
{
return dbus_message_set_error_name(_pvt->msg, n);
return dbus_message_set_error_name(_pvt->msg, n);
}
/*
@ -516,55 +516,55 @@ bool ErrorMessage::name(const char *n)
SignalMessage::SignalMessage(const char *name)
{
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
member(name);
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
member(name);
}
SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
{
_pvt->msg = dbus_message_new_signal(path, interface, name);
_pvt->msg = dbus_message_new_signal(path, interface, name);
}
bool SignalMessage::operator == (const SignalMessage &m) const
{
return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
}
const char *SignalMessage::interface() const
{
return dbus_message_get_interface(_pvt->msg);
return dbus_message_get_interface(_pvt->msg);
}
bool SignalMessage::interface(const char *i)
{
return dbus_message_set_interface(_pvt->msg, i);
return dbus_message_set_interface(_pvt->msg, i);
}
const char *SignalMessage::member() const
{
return dbus_message_get_member(_pvt->msg);
return dbus_message_get_member(_pvt->msg);
}
bool SignalMessage::member(const char *m)
{
return dbus_message_set_member(_pvt->msg, m);
return dbus_message_set_member(_pvt->msg, m);
}
const char *SignalMessage::path() const
{
return dbus_message_get_path(_pvt->msg);
return dbus_message_get_path(_pvt->msg);
}
char ** SignalMessage::path_split() const
char **SignalMessage::path_split() const
{
char ** p;
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
return p;
char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
return p;
}
bool SignalMessage::path(const char *p)
{
return dbus_message_set_path(_pvt->msg, p);
return dbus_message_set_path(_pvt->msg, p);
}
/*
@ -572,59 +572,59 @@ bool SignalMessage::path(const char *p)
CallMessage::CallMessage()
{
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
}
CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
{
_pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
_pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
}
bool CallMessage::operator == (const CallMessage &m) const
{
return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
}
const char *CallMessage::interface() const
{
return dbus_message_get_interface(_pvt->msg);
return dbus_message_get_interface(_pvt->msg);
}
bool CallMessage::interface(const char *i)
{
return dbus_message_set_interface(_pvt->msg, i);
return dbus_message_set_interface(_pvt->msg, i);
}
const char *CallMessage::member() const
{
return dbus_message_get_member(_pvt->msg);
return dbus_message_get_member(_pvt->msg);
}
bool CallMessage::member(const char *m)
{
return dbus_message_set_member(_pvt->msg, m);
return dbus_message_set_member(_pvt->msg, m);
}
const char *CallMessage::path() const
{
return dbus_message_get_path(_pvt->msg);
return dbus_message_get_path(_pvt->msg);
}
char ** CallMessage::path_split() const
char **CallMessage::path_split() const
{
char ** p;
dbus_message_get_path_decomposed(_pvt->msg, &p);
return p;
char **p;
dbus_message_get_path_decomposed(_pvt->msg, &p);
return p;
}
bool CallMessage::path(const char *p)
{
return dbus_message_set_path(_pvt->msg, p);
return dbus_message_set_path(_pvt->msg, p);
}
const char *CallMessage::signature() const
{
return dbus_message_get_signature(_pvt->msg);
return dbus_message_get_signature(_pvt->msg);
}
/*
@ -632,11 +632,11 @@ const char *CallMessage::signature() const
ReturnMessage::ReturnMessage(const CallMessage &callee)
{
_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
}
const char *ReturnMessage::signature() const
{
return dbus_message_get_signature(_pvt->msg);
return dbus_message_get_signature(_pvt->msg);
}

View file

@ -34,17 +34,18 @@
#include <dbus/dbus.h>
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL Message::Private
{
DBusMessage *msg;
DBusMessage *msg;
Private() : msg(0)
{}
Private() : msg(0)
{}
Private(DBusMessage *m) : msg(m)
{}
Private(DBusMessage *m) : msg(m)
{}
};
} /* namespace DBus */

View file

@ -40,7 +40,7 @@
using namespace DBus;
Object::Object(Connection &conn, const Path &path, const char *service)
: _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
: _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
{
}
@ -50,53 +50,53 @@ Object::~Object()
void Object::set_timeout(int new_timeout)
{
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
if(new_timeout < 0 && new_timeout != -1)
throw ErrorInvalidArgs("Bad timeout, cannot set it");
_default_timeout = new_timeout;
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
if (new_timeout < 0 && new_timeout != -1)
throw ErrorInvalidArgs("Bad timeout, cannot set it");
_default_timeout = new_timeout;
}
struct ObjectAdaptor::Private
{
static void unregister_function_stub(DBusConnection *, void *);
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
static void unregister_function_stub(DBusConnection *, void *);
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
};
static DBusObjectPathVTable _vtable =
{
ObjectAdaptor::Private::unregister_function_stub,
ObjectAdaptor::Private::message_function_stub,
NULL, NULL, NULL, NULL
{
ObjectAdaptor::Private::unregister_function_stub,
ObjectAdaptor::Private::message_function_stub,
NULL, NULL, NULL, NULL
};
void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data)
{
//TODO: what do we have to do here ?
//TODO: what do we have to do here ?
}
DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data)
{
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
if (o)
{
Message msg(new Message::Private(dmsg));
if (o)
{
Message msg(new Message::Private(dmsg));
debug_log("in object %s", o->path().c_str());
debug_log(" got message #%d from %s to %s",
msg.serial(),
msg.sender(),
msg.destination()
);
debug_log("in object %s", o->path().c_str());
debug_log(" got message #%d from %s to %s",
msg.serial(),
msg.sender(),
msg.destination()
);
return o->handle_message(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
else
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
return o->handle_message(msg)
? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
else
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
}
typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
@ -104,282 +104,282 @@ static ObjectAdaptorTable _adaptor_table;
ObjectAdaptor *ObjectAdaptor::from_path(const Path &path)
{
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
if (ati != _adaptor_table.end())
return ati->second;
if (ati != _adaptor_table.end())
return ati->second;
return NULL;
return NULL;
}
ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix)
{
ObjectAdaptorPList ali;
ObjectAdaptorPList ali;
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
size_t plen = prefix.length();
size_t plen = prefix.length();
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second);
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
ali.push_back(ati->second);
++ati;
}
++ati;
}
return ali;
return ali;
}
ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix)
{
ObjectPathList ali;
ObjectPathList ali;
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
size_t plen = prefix.length();
size_t plen = prefix.length();
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
{
std::string p = ati->second->path().substr(plen);
p = p.substr(0,p.find('/'));
ali.push_back(p);
}
++ati;
}
while (ati != _adaptor_table.end())
{
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
{
std::string p = ati->second->path().substr(plen);
p = p.substr(0, p.find('/'));
ali.push_back(p);
}
++ati;
}
ali.sort();
ali.unique();
ali.sort();
ali.unique();
return ali;
return ali;
}
ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path)
: Object(conn, path, conn.unique_name())
: Object(conn, path, conn.unique_name())
{
register_obj();
register_obj();
}
ObjectAdaptor::~ObjectAdaptor()
{
unregister_obj(false);
unregister_obj(false);
}
void ObjectAdaptor::register_obj()
{
debug_log("registering local object %s", path().c_str());
debug_log("registering local object %s", path().c_str());
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
{
throw ErrorNoMemory("unable to register object path");
}
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
{
throw ErrorNoMemory("unable to register object path");
}
_adaptor_table[path()] = this;
_adaptor_table[path()] = this;
}
void ObjectAdaptor::unregister_obj(bool)
{
_adaptor_table.erase(path());
_adaptor_table.erase(path());
debug_log("unregistering local object %s", path().c_str());
debug_log("unregistering local object %s", path().c_str());
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
}
void ObjectAdaptor::_emit_signal(SignalMessage &sig)
{
sig.path(path().c_str());
sig.path(path().c_str());
conn().send(sig);
conn().send(sig);
}
struct ReturnLaterError
{
const Tag *tag;
const Tag *tag;
};
bool ObjectAdaptor::handle_message(const Message &msg)
{
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
{
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
const char *member = cmsg.member();
const char *interface = cmsg.interface();
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_METHOD_CALL:
{
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
const char *member = cmsg.member();
const char *interface = cmsg.interface();
debug_log(" invoking method %s.%s", interface, member);
InterfaceAdaptor *ii = find_interface(interface);
if (ii)
{
try
{
Message ret = ii->dispatch_method(cmsg);
conn().send(ret);
}
catch(Error &e)
{
ErrorMessage em(cmsg, e.name(), e.message());
conn().send(em);
}
catch(ReturnLaterError &rle)
{
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
}
return true;
}
else
{
return false;
}
}
default:
{
return false;
}
}
debug_log(" invoking method %s.%s", interface, member);
InterfaceAdaptor *ii = find_interface(interface);
if (ii)
{
try
{
Message ret = ii->dispatch_method(cmsg);
conn().send(ret);
}
catch (Error &e)
{
ErrorMessage em(cmsg, e.name(), e.message());
conn().send(em);
}
catch (ReturnLaterError &rle)
{
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
}
return true;
}
else
{
return false;
}
}
default:
{
return false;
}
}
}
void ObjectAdaptor::return_later(const Tag *tag)
{
ReturnLaterError rle = { tag };
throw rle;
ReturnLaterError rle = { tag };
throw rle;
}
void ObjectAdaptor::return_now(Continuation *ret)
{
ret->_conn.send(ret->_return);
ret->_conn.send(ret->_return);
ContinuationMap::iterator di = _continuations.find(ret->_tag);
ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second;
delete di->second;
_continuations.erase(di);
_continuations.erase(di);
}
void ObjectAdaptor::return_error(Continuation *ret, const Error error)
{
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
ContinuationMap::iterator di = _continuations.find(ret->_tag);
ContinuationMap::iterator di = _continuations.find(ret->_tag);
delete di->second;
delete di->second;
_continuations.erase(di);
_continuations.erase(di);
}
ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag)
{
ContinuationMap::iterator di = _continuations.find(tag);
ContinuationMap::iterator di = _continuations.find(tag);
return di != _continuations.end() ? di->second : NULL;
return di != _continuations.end() ? di->second : NULL;
}
ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag)
: _conn(conn), _call(call), _return(_call), _tag(tag)
: _conn(conn), _call(call), _return(_call), _tag(tag)
{
_writer = _return.writer(); //todo: verify
_writer = _return.writer(); //todo: verify
}
/*
*/
ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service)
: Object(conn, path, service)
: Object(conn, path, service)
{
register_obj();
register_obj();
}
ObjectProxy::~ObjectProxy()
{
unregister_obj(false);
unregister_obj(false);
}
void ObjectProxy::register_obj()
{
debug_log("registering remote object %s", path().c_str());
debug_log("registering remote object %s", path().c_str());
_filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
conn().add_filter(_filtered);
_filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
conn().add_match(im.c_str());
++ii;
}
conn().add_filter(_filtered);
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
conn().add_match(im.c_str());
++ii;
}
}
void ObjectProxy::unregister_obj(bool throw_on_error)
{
debug_log("unregistering remote object %s", path().c_str());
debug_log("unregistering remote object %s", path().c_str());
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
conn().remove_match(im.c_str(), throw_on_error);
++ii;
}
conn().remove_filter(_filtered);
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
while (ii != _interfaces.end())
{
std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
conn().remove_match(im.c_str(), throw_on_error);
++ii;
}
conn().remove_filter(_filtered);
}
Message ObjectProxy::_invoke_method(CallMessage &call)
{
if (call.path() == NULL)
call.path(path().c_str());
if (call.path() == NULL)
call.path(path().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
return conn().send_blocking(call, get_timeout());
return conn().send_blocking(call, get_timeout());
}
bool ObjectProxy::_invoke_method_noreply(CallMessage &call)
{
if (call.path() == NULL)
call.path(path().c_str());
if (call.path() == NULL)
call.path(path().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
if (call.destination() == NULL)
call.destination(service().c_str());
return conn().send(call);
return conn().send(call);
}
bool ObjectProxy::handle_message(const Message &msg)
{
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_SIGNAL:
{
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
const char *interface = smsg.interface();
const char *member = smsg.member();
const char *objpath = smsg.path();
switch (msg.type())
{
case DBUS_MESSAGE_TYPE_SIGNAL:
{
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
const char *interface = smsg.interface();
const char *member = smsg.member();
const char *objpath = smsg.path();
if (objpath != path()) return false;
if (objpath != path()) return false;
debug_log("filtered signal %s(in %s) from %s to object %s",
member, interface, msg.sender(), objpath);
debug_log("filtered signal %s(in %s) from %s to object %s",
member, interface, msg.sender(), objpath);
InterfaceProxy *ii = find_interface(interface);
if (ii)
{
return ii->dispatch_signal(smsg);
}
else
{
return false;
}
}
default:
{
return false;
}
}
InterfaceProxy *ii = find_interface(interface);
if (ii)
{
return ii->dispatch_signal(smsg);
}
else
{
return false;
}
}
default:
{
return false;
}
}
}

View file

@ -36,107 +36,107 @@
using namespace DBus;
PendingCall::Private::Private(DBusPendingCall *dpc)
: call(dpc), dataslot(-1)
: call(dpc), dataslot(-1)
{
if (!dbus_pending_call_allocate_data_slot(&dataslot))
{
throw ErrorNoMemory("Unable to allocate data slot");
}
if (!dbus_pending_call_allocate_data_slot(&dataslot))
{
throw ErrorNoMemory("Unable to allocate data slot");
}
}
PendingCall::Private::~Private()
{
if (dataslot != -1)
{
dbus_pending_call_allocate_data_slot(&dataslot);
}
if (dataslot != -1)
{
dbus_pending_call_allocate_data_slot(&dataslot);
}
}
void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
{
PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
PendingCall pc(pvt);
pvt->slot(pc);
PendingCall pc(pvt);
pvt->slot(pc);
}
PendingCall::PendingCall(PendingCall::Private *p)
: _pvt(p)
: _pvt(p)
{
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
{
throw ErrorNoMemory("Unable to initialize pending call");
}
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
{
throw ErrorNoMemory("Unable to initialize pending call");
}
}
PendingCall::PendingCall(const PendingCall &c)
: _pvt(c._pvt)
: _pvt(c._pvt)
{
dbus_pending_call_ref(_pvt->call);
dbus_pending_call_ref(_pvt->call);
}
PendingCall::~PendingCall()
{
dbus_pending_call_unref(_pvt->call);
dbus_pending_call_unref(_pvt->call);
}
PendingCall &PendingCall::operator = (const PendingCall &c)
{
if (&c != this)
{
dbus_pending_call_unref(_pvt->call);
_pvt = c._pvt;
dbus_pending_call_ref(_pvt->call);
}
return *this;
if (&c != this)
{
dbus_pending_call_unref(_pvt->call);
_pvt = c._pvt;
dbus_pending_call_ref(_pvt->call);
}
return *this;
}
bool PendingCall::completed()
{
return dbus_pending_call_get_completed(_pvt->call);
return dbus_pending_call_get_completed(_pvt->call);
}
void PendingCall::cancel()
{
dbus_pending_call_cancel(_pvt->call);
dbus_pending_call_cancel(_pvt->call);
}
void PendingCall::block()
{
dbus_pending_call_block(_pvt->call);
dbus_pending_call_block(_pvt->call);
}
void PendingCall::data(void *p)
{
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{
throw ErrorNoMemory("Unable to initialize data slot");
}
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
{
throw ErrorNoMemory("Unable to initialize data slot");
}
}
void *PendingCall::data()
{
return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
}
Slot<void, PendingCall &>& PendingCall::slot()
{
return _pvt->slot;
return _pvt->slot;
}
Message PendingCall::steal_reply()
{
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
if (!dmsg)
{
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
if (!dmsg)
{
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
if (callComplete)
throw ErrorNoReply("No reply available");
else
throw ErrorNoReply("Call not complete");
}
if (callComplete)
throw ErrorNoReply("No reply available");
else
throw ErrorNoReply("Call not complete");
}
return Message(new Message::Private(dmsg));
return Message(new Message::Private(dmsg));
}

View file

@ -34,19 +34,20 @@
#include <dbus/dbus.h>
namespace DBus {
namespace DBus
{
struct DXXAPILOCAL PendingCall::Private
{
DBusPendingCall *call;
int dataslot;
Slot<void, PendingCall &> slot;
Private(DBusPendingCall *);
DBusPendingCall *call;
int dataslot;
Slot<void, PendingCall &> slot;
~Private();
Private(DBusPendingCall *);
static void notify_stub(DBusPendingCall *dpc, void *data);
~Private();
static void notify_stub(DBusPendingCall *dpc, void *data);
};
} /* namespace DBus */

View file

@ -42,13 +42,13 @@ using namespace std;
Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) :
_handler(handler),
_fd_write (0),
_fd_read (0),
_fd_write(0),
_fd_read(0),
_data(data)
{
int fd[2];
if(pipe(fd) == 0)
if (pipe(fd) == 0)
{
_fd_read = fd[0];
_fd_write = fd[1];
@ -56,23 +56,23 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c
}
else
{
throw Error("PipeError:errno", toString(errno).c_str());
throw Error("PipeError:errno", toString(errno).c_str());
}
}
void Pipe::write(const void *buffer, unsigned int nbytes)
{
// first write the size into the pipe...
::write(_fd_write, static_cast <const void*> (&nbytes), sizeof(nbytes));
::write(_fd_write, static_cast <const void *>(&nbytes), sizeof(nbytes));
// ...then write the real data
::write(_fd_write, buffer, nbytes);
::write(_fd_write, buffer, nbytes);
}
ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
{
{
// first read the size from the pipe...
::read(_fd_read, &nbytes, sizeof (nbytes));
::read(_fd_read, &nbytes, sizeof(nbytes));
//ssize_t size = 0;
return ::read(_fd_read, buffer, nbytes);
@ -80,5 +80,5 @@ ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
void Pipe::signal()
{
::write(_fd_write, '\0', 1);
::write(_fd_write, '\0', 1);
}

View file

@ -35,117 +35,117 @@ using namespace DBus;
static const char *properties_name = "org.freedesktop.DBus.Properties";
PropertiesAdaptor::PropertiesAdaptor()
: InterfaceAdaptor(properties_name)
: InterfaceAdaptor(properties_name)
{
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
register_method(PropertiesAdaptor, Get, Get);
register_method(PropertiesAdaptor, Set, Set);
}
Message PropertiesAdaptor::Get(const CallMessage &call)
{
MessageIter ri = call.reader();
MessageIter ri = call.reader();
std::string iface_name;
std::string property_name;
std::string iface_name;
std::string property_name;
ri >> iface_name >> property_name;
ri >> iface_name >> property_name;
debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str());
debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str());
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
if (!interface)
throw ErrorFailed("requested interface not found");
if (!interface)
throw ErrorFailed("requested interface not found");
Variant *value = interface->get_property(property_name);
Variant *value = interface->get_property(property_name);
if (!value)
throw ErrorFailed("requested property not found");
if (!value)
throw ErrorFailed("requested property not found");
on_get_property(*interface, property_name, *value);
on_get_property(*interface, property_name, *value);
ReturnMessage reply(call);
ReturnMessage reply(call);
MessageIter wi = reply.writer();
MessageIter wi = reply.writer();
wi << *value;
return reply;
wi << *value;
return reply;
}
Message PropertiesAdaptor::Set(const CallMessage &call)
{
MessageIter ri = call.reader();
MessageIter ri = call.reader();
std::string iface_name;
std::string property_name;
Variant value;
std::string iface_name;
std::string property_name;
Variant value;
ri >> iface_name >> property_name >> value;
ri >> iface_name >> property_name >> value;
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
if (!interface)
throw ErrorFailed("requested interface not found");
if (!interface)
throw ErrorFailed("requested interface not found");
on_set_property(*interface, property_name, value);
on_set_property(*interface, property_name, value);
interface->set_property(property_name, value);
interface->set_property(property_name, value);
ReturnMessage reply(call);
ReturnMessage reply(call);
return reply;
return reply;
}
IntrospectedInterface * PropertiesAdaptor::introspect() const
IntrospectedInterface *PropertiesAdaptor::introspect() const
{
static IntrospectedArgument Get_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", false },
{ 0, 0, 0 }
};
static IntrospectedArgument Set_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Properties_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Properties_interface =
{
properties_name,
Properties_methods,
Properties_signals,
Properties_properties
};
return &Properties_interface;
static IntrospectedArgument Get_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", false },
{ 0, 0, 0 }
};
static IntrospectedArgument Set_args[] =
{
{ "interface_name", "s", true },
{ "property_name", "s", true },
{ "value", "v", true },
{ 0, 0, 0 }
};
static IntrospectedMethod Properties_methods[] =
{
{ "Get", Get_args },
{ "Set", Set_args },
{ 0, 0 }
};
static IntrospectedMethod Properties_signals[] =
{
{ 0, 0 }
};
static IntrospectedProperty Properties_properties[] =
{
{ 0, 0, 0, 0 }
};
static IntrospectedInterface Properties_interface =
{
properties_name,
Properties_methods,
Properties_signals,
Properties_properties
};
return &Properties_interface;
}
PropertiesProxy::PropertiesProxy()
: InterfaceProxy(properties_name)
: InterfaceProxy(properties_name)
{
}
Variant PropertiesProxy::Get(const std::string &iface, const std::string &property)
{
//todo
Variant v;
return v;
Variant v;
return v;
}
void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value)

View file

@ -36,7 +36,7 @@
using namespace DBus;
Server::Private::Private(DBusServer *s)
: server(s)
: server(s)
{
}
@ -46,31 +46,31 @@ Server::Private::~Private()
void Server::Private::on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data)
{
Server *s = static_cast<Server *>(data);
Server *s = static_cast<Server *>(data);
Connection nc (new Connection::Private(conn, s->_pvt.get()));
Connection nc(new Connection::Private(conn, s->_pvt.get()));
s->_pvt->connections.push_back(nc);
s->_pvt->connections.push_back(nc);
s->on_new_connection(nc);
s->on_new_connection(nc);
debug_log("incoming connection 0x%08x", conn);
debug_log("incoming connection 0x%08x", conn);
}
Server::Server(const char *address)
{
InternalError e;
DBusServer *server = dbus_server_listen(address, e);
InternalError e;
DBusServer *server = dbus_server_listen(address, e);
if (e) throw Error(e);
if (e) throw Error(e);
debug_log("server 0x%08x listening on %s", server, address);
debug_log("server 0x%08x listening on %s", server, address);
_pvt = new Private(server);
_pvt = new Private(server);
dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
setup(default_dispatcher);
setup(default_dispatcher);
}
/*
Server::Server(const Server &s)
@ -81,49 +81,49 @@ Server::Server(const Server &s)
*/
Server::~Server()
{
dbus_server_unref(_pvt->server);
dbus_server_unref(_pvt->server);
}
Dispatcher *Server::setup(Dispatcher *dispatcher)
{
debug_log("registering stubs for server %p", _pvt->server);
debug_log("registering stubs for server %p", _pvt->server);
Dispatcher *prev = _pvt->dispatcher;
Dispatcher *prev = _pvt->dispatcher;
dbus_server_set_watch_functions(
_pvt->server,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_server_set_watch_functions(
_pvt->server,
Dispatcher::Private::on_add_watch,
Dispatcher::Private::on_rem_watch,
Dispatcher::Private::on_toggle_watch,
dispatcher,
0
);
dbus_server_set_timeout_functions(
_pvt->server,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
dbus_server_set_timeout_functions(
_pvt->server,
Dispatcher::Private::on_add_timeout,
Dispatcher::Private::on_rem_timeout,
Dispatcher::Private::on_toggle_timeout,
dispatcher,
0
);
_pvt->dispatcher = dispatcher;
_pvt->dispatcher = dispatcher;
return prev;
return prev;
}
bool Server::operator == (const Server &s) const
{
return _pvt->server == s._pvt->server;
return _pvt->server == s._pvt->server;
}
bool Server::listening() const
{
return dbus_server_get_is_connected(_pvt->server);
return dbus_server_get_is_connected(_pvt->server);
}
void Server::disconnect()
{
dbus_server_disconnect(_pvt->server);
dbus_server_disconnect(_pvt->server);
}

View file

@ -35,21 +35,22 @@
#include <dbus/dbus.h>
namespace DBus {
struct DXXAPILOCAL Server::Private
namespace DBus
{
DBusServer *server;
Dispatcher *dispatcher;
struct DXXAPILOCAL Server::Private
{
DBusServer *server;
ConnectionList connections;
Dispatcher *dispatcher;
Private(DBusServer *);
ConnectionList connections;
~Private();
Private(DBusServer *);
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data);
~Private();
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data);
};
} /* namespace DBus */

View file

@ -37,70 +37,70 @@
using namespace DBus;
Variant::Variant()
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
{
}
Variant::Variant(MessageIter &it)
: _msg(CallMessage())
: _msg(CallMessage())
{
MessageIter vi = it.recurse();
MessageIter mi = _msg.writer();
vi.copy_data(mi);
MessageIter vi = it.recurse();
MessageIter mi = _msg.writer();
vi.copy_data(mi);
}
Variant &Variant::operator = (const Variant &v)
{
if (&v != this)
{
_msg = v._msg;
}
return *this;
if (&v != this)
{
_msg = v._msg;
}
return *this;
}
void Variant::clear()
{
CallMessage empty;
_msg = empty;
CallMessage empty;
_msg = empty;
}
const Signature Variant::signature() const
{
char *sigbuf = reader().signature();
char *sigbuf = reader().signature();
Signature signature = sigbuf;
Signature signature = sigbuf;
free(sigbuf);
free(sigbuf);
return signature;
return signature;
}
MessageIter &operator << (MessageIter &iter, const Variant &val)
{
const Signature sig = val.signature();
const Signature sig = val.signature();
MessageIter rit = val.reader();
MessageIter wit = iter.new_variant(sig.c_str());
MessageIter rit = val.reader();
MessageIter wit = iter.new_variant(sig.c_str());
rit.copy_data(wit);
rit.copy_data(wit);
iter.close_container(wit);
iter.close_container(wit);
return iter;
return iter;
}
MessageIter &operator >> (MessageIter &iter, Variant &val)
{
if (iter.type() != DBUS_TYPE_VARIANT)
throw ErrorInvalidArgs("variant type expected");
if (iter.type() != DBUS_TYPE_VARIANT)
throw ErrorInvalidArgs("variant type expected");
val.clear();
val.clear();
MessageIter vit = iter.recurse();
MessageIter mit = val.writer();
MessageIter vit = iter.recurse();
MessageIter mit = val.writer();
vit.copy_data(mit);
vit.copy_data(mit);
return ++iter;
return ++iter;
}