Python / C++ application D-Bus usage issues
Kip Warner
kip at thevertigo.com
Mon Dec 17 22:18:28 PST 2012
On Tue, 2012-12-18 at 08:11 +0200, Tanu Kaskinen wrote:
> I don't know the implementation of dbus-send. If you're saying that
> dbus-send calls Introspect even when you use it to just send a signal, I
> believe you. I don't know why it does that, but if it does, it probably
> has its reasons. Whether or not you can just forget about that depends
> on whether this causes problems for you or not.
I am thinking it probably does this automatically. In any case, since I
replaced the proxy logic in Python with sending the other technique we
were discussing, the Introspect problem disappeared. However, the signal
I am sending the C++ application from my Python application doesn't seem
to be received.
From the Python side...
# Fire off the ready signal...
message = SignalMessage(DBUS_OBJECT_PATH, DBUS_INTERFACE,
"Ready")
self._sessionBus.send_message(message)
self._sessionBus.flush()
On the recipient C++ side, I register on the session bus like so...
// Register on the session bus...
void DBusInterface::RegisterOnSessionBus()
{
// Alert user...
Message(Console::Info) << "d-bus: registering on the session bus..."
<< endl;
// Clear the bus error variable...
dbus_error_init(&m_Error);
// Open a connection the session bus...
m_Connection = dbus_bus_get(DBUS_BUS_SESSION, &m_Error);
// Failed...
if(!m_Connection)
{
// Alert user and terminate...
Message(Console::Error)
<< "d-bus: could not connect with the session bus ("
<< m_Error.message << ")" << endl;
exit(EXIT_FAILURE);
}
// Register ourselves on the session bus...
const int Result = dbus_bus_request_name(
m_Connection, m_BusName.c_str(),
DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
DBUS_NAME_FLAG_REPLACE_EXISTING |
DBUS_NAME_FLAG_DO_NOT_QUEUE,
&m_Error);
// Failed...
if(dbus_error_is_set(&m_Error))
{
// Alert user and terminate...
Message(Console::Error)
<< "d-bus: could not register service with session
bus... ("
<< m_Error.message << ")" << endl;
// Cleanup and terminate...
dbus_error_free(&m_Error);
exit(EXIT_FAILURE);
}
// There's probably some other instance already running and it's
not
// ourselves...
if(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != Result &&
DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER != Result)
{
// Alert user and terminate...
Message(Console::Error)
<< "d-bus: already running instance detected that could not
be replaced..."
<< endl;
// Cleanup and terminate...
exit(EXIT_FAILURE);
}
// Add a rule so we can receive signals of interest...
// Format rule...
stringstream MatchRule;
MatchRule << "type='signal'," << "interface='" << m_Interface <<
"'";
// Register...
dbus_bus_add_match(m_Connection, MatchRule.str().c_str(),
&m_Error);
dbus_connection_flush(m_Connection);
// Failed...
if(dbus_error_is_set(&m_Error))
{
// Alert user and terminate...
Message(Console::Error)
<< "d-bus: match error... ("
<< m_Error.message << ")" << endl;
// Cleanup and terminate...
dbus_error_free(&m_Error);
exit(EXIT_FAILURE);
}
}
...then I try to listen for the Ready signal I fired from the Python
code with the following blocking method...
// Wait for a D-Bus signal before unblocking or throw an error...
void DBusInterface::WaitRemoteStart()
{
// Flag toggled when we received successfully the Ready signal...
bool Ready = false;
// Keep checking the message queue, without hammering the CPU, until
the
// Ready signal arrives...
while(!Ready)
{
// Alert user...
Message(Console::Info)
<< "d-bus: awaiting ready signal, please wait..." << endl;
// Block until next message becomes available and check for
error...
if(!dbus_connection_read_write(m_Connection, -1))
throw string("d-bus: connection closed prematurely...");
// Retrieve the message...
DBusMessage *IncomingMessage =
dbus_connection_pop_message(m_Connection);
// Failed...
if(!IncomingMessage)
{
// Alert user, then try again...
Message(Console::Error)
<< "d-bus: empty message queue, trying again..." <<
endl;
continue;
}
// Verify this was the Ready signal...
Ready = dbus_message_is_signal(
IncomingMessage, m_Interface.c_str(),
m_ReadySignal.c_str());
// Cleanup...
dbus_message_unref(IncomingMessage);
}
}
Unfortunately the signal never seems to be received. I thought maybe the
bus was just buffering messages before delivering them to the recipient,
but I was careful to make sure I called self._sessionBus.flush() after
sending the signal.
--
Kip Warner -- Software Engineer
OpenPGP encrypted/signed mail preferred
http://www.thevertigo.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/dbus/attachments/20121217/76c2b2b1/attachment-0001.pgp>
More information about the dbus
mailing list