Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-04

DBus in GUI application

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Krzysztof

Hi,

DBus documentation give me a headache. Does anyone know solution how to implement DBus in GUI main loop (for signals listening)? I have tried with threads but have two problems:
1. Not all signals are catched (randomly)
2. Deadlock when main thread trying to use dbus methods

Regards

Reply by email

Luca Olivetti
to Krzysztof

El 04/04/14 17:46, Krzysztof ha escrit:

Show quoted text 7 lines
Hi, DBus documentation give me a headache. Does anyone know solution how to implement DBus in GUI main loop (for signals listening)? I have tried with threads but have two problems: 1. Not all signals are catched (randomly) 2. Deadlock when main thread trying to use dbus methods

Last time (and the only time) I wrote a dbus server was 5 years ago (so I used the plain translation of the C api and a now obsolete version of dbus), but it was a daemon (not a gui program) with more or less this structure:

while not terminated do
begin
   DbusCycle;
   { do other things }
end;

and DbusCycle was managing a non-blocking dbus connection like this:

begin
  //non blocking read of the next available message
  if connnil then
  begin
    if dbus_connection_get_is_connected(conn)=0 then
    begin
       Logger.Error('perdida conexion con bus');
       conn:=nil;
    end;
  end;
  if conn=nil then ConnectToSystembus;
  if conn=nil then exit;
  dbus_connection_read_write(conn,0);
  msg:=dbus_connection_pop_message(conn);
  if msg=nil then exit;
  lastfailed:=false;
  // check this is a method call for the right interface & method
  if (dbus_message_is_method_call(msg,

'es.wetron.almacen_tapas.method.Status', 'GetStatus') 0) then reply_to_getstatus_call else
if (dbus_message_is_method_call(msg,
'es.wetron.almacen_tapas.method.Status', 'GetFifo') 0) then reply_to_getfifo_call else
if (dbus_message_is_method_call(msg,
'es.wetron.almacen_tapas.method.Simulation', 'Simulate') 0) then

     reply_to_simulate_call;
  // free the message
  dbus_message_unref(msg);

end;

not much help, I know, but it worked (btw: since I also controlled the client, in hindsight it was a stupid decision: I could have used something more cross-platform like a socket).

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007

Reply by email

Krzysztof
to Luca Olivetti

Thanks for sharing. Your code is working fine. But did you notice deadlocks (randomly)? For example if I use thread for signals listening. And then main thread (e.g. button click) want to call some method from same dbus interface. Even if try to use different connection by calling dbus_bus_get(DBUS_BUS_SESSION, @err), I'm getting same pointer. This is my code for method call:

var
  msg: PDBusMessage;
  pending: PDBusPendingCall;
begin
  if conn = nil then Exit;
  // create a new method call and check for errors
  msg := dbus_message_new_method_call('org.mpris.MediaPlayer2.clementine',
// target for the method call
                                      '/Player', // object to call on
                                      'org.freedesktop.MediaPlayer',
// interface to call on
                                      'Next'); // method name
  if (msg = nil) then
  begin
    WriteLn('Message Null');
    Exit;
  end;
  // send message and get a handle for a reply
  if (dbus_connection_send_with_reply(conn, msg, @pending, -1) = 0)
then // -1 is default timeout
  begin
    WriteLn('Out Of Memory!');
    Exit;
  end;
  if (pending = nil) then
  begin
    WriteLn('Pending Call Null');
    Exit;
  end;
  dbus_connection_flush(conn);
  WriteLn('Request Sent');
  // free message
  dbus_message_unref(msg);
  // block until we recieve a reply
  dbus_pending_call_block(pending);
  // get the reply message
  msg := dbus_pending_call_steal_reply(pending);
  if (msg = nil) then
  begin
    WriteLn('Reply Null');
    Exit;
  end;
  // free the pending message handle
  dbus_pending_call_unref(pending);
  // free reply
  dbus_message_unref(msg);
end;

2014-04-05 15:35 GMT+02:00 Luca Olivetti :

Show quoted text 71 lines
El 04/04/14 17:46, Krzysztof ha escrit: > Hi, > > DBus documentation give me a headache. Does anyone know solution how > to implement DBus in GUI main loop (for signals listening)? I have > tried with threads but have two problems: > 1. Not all signals are catched (randomly) > 2. Deadlock when main thread trying to use dbus methods Last time (and the only time) I wrote a dbus server was 5 years ago (so I used the plain translation of the C api and a now obsolete version of dbus), but it was a daemon (not a gui program) with more or less this structure: while not terminated do begin DbusCycle; { do other things } end; and DbusCycle was managing a non-blocking dbus connection like this: begin //non blocking read of the next available message if connnil then begin if dbus_connection_get_is_connected(conn)=0 then begin Logger.Error('perdida conexion con bus'); conn:=nil; end; end; if conn=nil then ConnectToSystembus; if conn=nil then exit; dbus_connection_read_write(conn,0); msg:=dbus_connection_pop_message(conn); if msg=nil then exit; lastfailed:=false; // check this is a method call for the right interface & method if (dbus_message_is_method_call(msg, 'es.wetron.almacen_tapas.method.Status', 'GetStatus') 0) then reply_to_getstatus_call else if (dbus_message_is_method_call(msg, 'es.wetron.almacen_tapas.method.Status', 'GetFifo') 0) then reply_to_getfifo_call else if (dbus_message_is_method_call(msg, 'es.wetron.almacen_tapas.method.Simulation', 'Simulate') 0) then reply_to_simulate_call; // free the message dbus_message_unref(msg); end; not much help, I know, but it worked (btw: since I also controlled the client, in hindsight it was a stupid decision: I could have used something more cross-platform like a socket). Bye -- Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007 _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email