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