Sign in Join

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

Mailing lists / fpc-pascal / 2011-01

D-Bus. Non blocking listening for signals

28 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Unknown author

Hi,

Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) Admin give me solution and feedback, but this solution doesn't work well and i think he don't read my last comment.
So, maybe someone have this same problem. There is good demo for d-bus rewrited line by line from official C example. It works fine, but this is console demo. This demo listen for signals in main loop. In GUI application, this example blocks user interface. I received a solution to use Application.OnIdle event for check for signal. It works, but not detect all signals. If host send 10 this same signals, my application detect only 4-6.
This problem raise after upgrade d-bus interface from 0.92 to 1.2.16 two months ago. Previously, I could use timers and threads for listening signals.

Regard

Henry Vermaak
to Unknown author
Show quoted text 14 lines
Hi, Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) Admin give me solution and feedback, but this solution doesn't work well and i think he don't read my last comment. So, maybe someone have this same problem. There is good demo for d-bus rewrited line by line from official C example. It works fine, but this is console demo. This demo listen for signals in main loop. In GUI application, this example blocks user interface. I received a solution to use Application.OnIdle event for check for signal. It works, but not detect all signals. If host send 10 this same signals, my application detect only 4-6. This problem raise after upgrade d-bus interface from 0.92 to 1.2.16 two months ago. Previously, I could use timers and threads for listening signals.

You may already know this, but it may help to point out that the OnIdle event won't fire if there are no other events. For example, you'll have to move your mouse or hit the keyboard for the OnIdle event to be called. I don't know if this will affect talking to dbus (does it queue up the signals?).

Henry

Unknown author
to Henry Vermaak

W dniu 02.01.2011 20:11, Henry Vermaak pisze:

Show quoted text 22 lines
On 2 January 2011 18:49, wrote: > Hi, > > Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) > Admin give me solution and feedback, but this solution doesn't work well and > i think he don't read my last comment. > So, maybe someone have this same problem. There is good demo for d-bus > rewrited line by line from official C example. It works fine, but this is > console demo. This demo listen for signals in main loop. In GUI application, > this example blocks user interface. I received a solution to use > Application.OnIdle event for check for signal. It works, but not detect all > signals. If host send 10 this same signals, my application detect only 4-6. > This problem raise after upgrade d-bus interface from 0.92 to 1.2.16 two > months ago. Previously, I could use timers and threads for listening > signals. You may already know this, but it may help to point out that the OnIdle event won't fire if there are no other events. For example, you'll have to move your mouse or hit the keyboard for the OnIdle event to be called. I don't know if this will affect talking to dbus (does it queue up the signals?). Henry

Yes, but I noticed that when there are no events, OnIdle is fired even so (at 5 seconds cycle). I thought it was enough to catch signal, but maybe it's too long and signals may have short live. C example uses glib main loop to check signals. I see that free pascal have some glib librarys. Can I somehow use it (I do not know what it is)? I need this solution only for linux

Henry Vermaak
to Unknown author
Show quoted text 15 lines
> > You may already know this, but it may help to point out that the > OnIdle event won't fire if there are no other events.  For example, > you'll have to move your mouse or hit the keyboard for the OnIdle > event to be called.  I don't know if this will affect talking to dbus > (does it queue up the signals?). > > Henry Yes, but I noticed that when there are no events, OnIdle is fired even so (at 5 seconds cycle). I thought it was enough to catch signal, but maybe it's too long and signals may have short live. C example uses glib main loop to check signals. I see that free pascal have some glib librarys. Can I somehow use it (I do not know what it is)? I need this solution only for linux

I had a quick look at the dbus functions. Perhaps you can use dbus_connection_set_wakeup_main_function to set up a function that wakes up your main loop (containing something like: g_main_context_wakeup(g_main_context_default) for gtk+). This will fire the OnIdle event where you can read the message.

Another solution can be to launch a thread that executes a loop of dbus reads. You can then communicate back to the main thread.

Henry

Unknown author
to Henry Vermaak

W dniu 02.01.2011 21:36, Henry Vermaak pisze:

Show quoted text 24 lines
On 2 January 2011 19:42, wrote: >> You may already know this, but it may help to point out that the >> OnIdle event won't fire if there are no other events. For example, >> you'll have to move your mouse or hit the keyboard for the OnIdle >> event to be called. I don't know if this will affect talking to dbus >> (does it queue up the signals?). >> >> Henry > Yes, but I noticed that when there are no events, OnIdle is fired even so > (at 5 seconds cycle). I thought it was enough to catch signal, but maybe > it's too long and signals may have short live. C example uses glib main loop > to check signals. I see that free pascal have some glib librarys. Can I > somehow use it (I do not know what it is)? I need this solution only for > linux I had a quick look at the dbus functions. Perhaps you can use dbus_connection_set_wakeup_main_function to set up a function that wakes up your main loop (containing something like: g_main_context_wakeup(g_main_context_default) for gtk+). This will fire the OnIdle event where you can read the message. Another solution can be to launch a thread that executes a loop of dbus reads. You can then communicate back to the main thread. Henry

Wow, thanks! I read few examples in different programing languages, but nowhere was no mention of this procedure. Although this example doesn't work (or I am doing something wrong):
dbus_connection_set_wakeup_main_function(conn, @g_main_context_wakeup, g_main_context_default, nil);
But I declared my own procedure where I call checking for signals:

procedure TestTest(data: Pointer); cdecl;
begin
   Form1.CheckForMessage;
end;
dbus_connection_set_wakeup_main_function(conn, @TestTest, nil, nil);

And it works perfect! :) . Thanks again.

BTW: About your suggestion to use threads. I used threads before and it worked very long on my application. But it stopped after upgrade d-bus interface. That is why I post this problem

Regards.

Henry Vermaak
to Unknown author
Show quoted text 16 lines
> I had a quick look at the dbus functions.  Perhaps you can use > dbus_connection_set_wakeup_main_function to set up a function that > wakes up your main loop (containing something like: > g_main_context_wakeup(g_main_context_default) for gtk+).  This will > fire the OnIdle event where you can read the message. > > Another solution can be to launch a thread that executes a loop of > dbus reads.  You can then communicate back to the main thread. > > Henry Wow, thanks! I read few examples in different programing languages, but nowhere was no mention of this procedure. Although this example doesn't work (or I am doing something wrong): dbus_connection_set_wakeup_main_function(conn, @g_main_context_wakeup, g_main_context_default, nil);

No, I meant almost like you did below.

Show quoted text 5 lines
But I declared my own procedure where I call checking for signals: procedure TestTest(data: Pointer); cdecl; begin  Form1.CheckForMessage;

Here I would use Application.QueueAsyncCall to queue a method to check for messages, then g_main_context_wakeup(g_main_context_default), which is asynchronous, so you don't block your dbus callback. This may not be a problem.

The way you've done it is probably OK!

Henry

Michael Van Canneyt
to Unknown author: Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) Admin give me…
Show quoted text 13 lines
Hi, Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) Admin give me solution and feedback, but this solution doesn't work well and i think he don't read my last comment. So, maybe someone have this same problem. There is good demo for d-bus rewrited line by line from official C example. It works fine, but this is console demo. This demo listen for signals in main loop. In GUI application, this example blocks user interface. I received a solution to use Application.OnIdle event for check for signal. It works, but not detect all signals. If host send 10 this same signals, my application detect only 4-6. This problem raise after upgrade d-bus interface from 0.92 to 1.2.16 two months ago. Previously, I could use timers and threads for listening signals.

The admin (me) did see your comment but didn't find time yet to investigate the problem in great length :)

However, it seems that Henry Vermaak gave you a solution. I am glad he did, because I have written a complete set of D-BUS components which I was about to publish, and they would suffer from the same problem when used in a GUI app. So now I know that I should create an integration with the Lazarus message loop.

Michael.

Unknown author
to Michael Van Canneyt

W dniu 02.01.2011 23:21, Michael Van Canneyt pisze:

Show quoted text 34 lines
On Sun, 2 Jan 2011, wrote: > Hi, > > Month ago I posted a bug (http://bugs.freepascal.org/view.php?id=18117) > Admin give me solution and feedback, but this solution doesn't work > well and i think he don't read my last comment. > So, maybe someone have this same problem. There is good demo for > d-bus rewrited line by line from official C example. It works fine, > but this is console demo. This demo listen for signals in main loop. > In GUI application, this example blocks user interface. I received a > solution to use Application.OnIdle event for check for signal. It > works, but not detect all signals. If host send 10 this same signals, > my application detect only 4-6. > This problem raise after upgrade d-bus interface from 0.92 to 1.2.16 > two months ago. Previously, I could use timers and threads for > listening signals. The admin (me) did see your comment but didn't find time yet to investigate the problem in great length :) However, it seems that Henry Vermaak gave you a solution. I am glad he did, because I have written a complete set of D-BUS components which I was about to publish, and they would suffer from the same problem when used in a GUI app. So now I know that I should create an integration with the Lazarus message loop. Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Sorry for refreshing, but the problem is still present :( . It works perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my friends computer. For example, one of my friend have this same laptop as me and exactly this same version of ubuntu (64 bit too). My application find signals only when he moving mouse cursor over main form (on idle event is fired in which I check for signals too). It looks like method dbus_connection_set_wakeup_main_function doesn't register wake up function properly. This is procedure, not function so I don't even know if there was error.
I copy source of my program to ubuntu 10.10 32bit on my virtual mashine and compile on latest SVN version of lazarus (like on 64 bit ubuntu). This same problem. I debug this and wake up function is never called in client when dbus host send signals. I have no idea why on 64 bit (and only on my) it works ok. Some external library is responsible for this? All computers are upgraded to latest version, so we have this same dbus library.

Regards

Michael Van Canneyt
to Unknown author
Show quoted text 9 lines
Sorry for refreshing, but the problem is still present :( . It works perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my friends computer. For example, one of my friend have this same laptop as me and exactly this same version of ubuntu (64 bit too). My application find signals only when he moving mouse cursor over main form (on idle event is fired in which I check for signals too). It looks like method dbus_connection_set_wakeup_main_function doesn't register wake up function properly. This is procedure, not function so I don't even know if there was error.

That can of course be, but this is not under our control.

Show quoted text 6 lines
I copy source of my program to ubuntu 10.10 32bit on my virtual mashine and compile on latest SVN version of lazarus (like on 64 bit ubuntu). This same problem. I debug this and wake up function is never called in client when dbus host send signals. I have no idea why on 64 bit (and only on my) it works ok. Some external library is responsible for this? All computers are upgraded to latest version, so we have this same dbus library.

Do they run the same desktop ?

Can you please provide testprograms (client and server) so I can run some tests ?

Michael.

Unknown author
to Michael Van Canneyt

W dniu 10.01.2011 20:41, Michael Van Canneyt pisze:

Show quoted text 35 lines
On Mon, 10 Jan 2011, wrote: > Sorry for refreshing, but the problem is still present :( . It works > perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my > friends computer. For example, one of my friend have this same laptop > as me and exactly this same version of ubuntu (64 bit too). My > application find signals only when he moving mouse cursor over main > form (on idle event is fired in which I check for signals too). It > looks like method dbus_connection_set_wakeup_main_function doesn't > register wake up function properly. This is procedure, not function > so I don't even know if there was error. That can of course be, but this is not under our control. > I copy source of my program to ubuntu 10.10 32bit on my virtual > mashine and compile on latest SVN version of lazarus (like on 64 bit > ubuntu). This same problem. I debug this and wake up function is > never called in client when dbus host send signals. I have no idea > why on 64 bit (and only on my) it works ok. Some external library is > responsible for this? All computers are upgraded to latest version, > so we have this same dbus library. Do they run the same desktop ? Can you please provide testprograms (client and server) so I can run some tests ? Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

I sent you demo with details via e-mail (your free pascal account)

Dibo.

Unknown author
to Michael Van Canneyt: That can of course be, but this is not under our control. Do they run the same desktop ?…

W dniu 10.01.2011 20:41, Michael Van Canneyt pisze:

Show quoted text 35 lines
On Mon, 10 Jan 2011, wrote: > Sorry for refreshing, but the problem is still present :( . It works > perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my > friends computer. For example, one of my friend have this same laptop > as me and exactly this same version of ubuntu (64 bit too). My > application find signals only when he moving mouse cursor over main > form (on idle event is fired in which I check for signals too). It > looks like method dbus_connection_set_wakeup_main_function doesn't > register wake up function properly. This is procedure, not function > so I don't even know if there was error. That can of course be, but this is not under our control. > I copy source of my program to ubuntu 10.10 32bit on my virtual > mashine and compile on latest SVN version of lazarus (like on 64 bit > ubuntu). This same problem. I debug this and wake up function is > never called in client when dbus host send signals. I have no idea > why on 64 bit (and only on my) it works ok. Some external library is > responsible for this? All computers are upgraded to latest version, > so we have this same dbus library. Do they run the same desktop ? Can you please provide testprograms (client and server) so I can run some tests ? Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Did you receive my mailwith demo? I think I found temporary solution. In glib2 is procedure: g_main_context_set_poll_func(g_main_context_default, @CheckForSignalProc);

It seems that application main loop call registered CheckForSignalProc on each loop cycle without blocking user interface and it works. But I do not know if I understand the documentation:

"Sets the function to use to handle polling of file descriptors. It will be used instead of the |poll()| system call (or GLib's replacement function, which is used where |poll()| isn't available).

This function could possibly be used to integrate the GLib event loop with an external event loop."

"integrate the GLib event loop with an external event loop" - I think this is what I want.

My concerns:
1. How does it affect to performance? Is it too often calledfor dbus?
2. Glib is most used by GTK. Will this work when I compile project with QT interface for KDE? (my future plans). I do not want to force users to install whole GTK librarys when they areusing only QT

Unknown author
to Unknown author
Show quoted text 36 lines
W dniu 10.01.2011 20:41, Michael Van Canneyt pisze: > > > On Mon, 10 Jan 2011, wrote: > >> Sorry for refreshing, but the problem is still present :( . It works >> perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my friends >> computer. For example, one of my friend have this same laptop as me and >> exactly this same version of ubuntu (64 bit too). My application find >> signals only when he moving mouse cursor over main form (on idle event is >> fired in which I check for signals too). It looks like method >> dbus_connection_set_wakeup_main_function doesn't register wake up function >> properly. This is procedure, not function so I don't even know if there >> was error. > > That can of course be, but this is not under our control. > >> I copy source of my program to ubuntu 10.10 32bit on my virtual mashine >> and compile on latest SVN version of lazarus (like on 64 bit ubuntu). This >> same problem. I debug this and wake up function is never called in client >> when dbus host send signals. I have no idea why on 64 bit (and only on my) >> it works ok. Some external library is responsible for this? All computers >> are upgraded to latest version, so we have this same dbus library. > > Do they run the same desktop ? > > Can you please provide testprograms (client and server) so I can run some > tests ? > > Michael. > > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal > Did you receive my mailwith demo?

Yes, I even debugged some things, but found no solution yet.

Show quoted text 7 lines
I think I found temporary solution. In glib2 is procedure: g_main_context_set_poll_func(g_main_context_default, @CheckForSignalProc); It seems that application main loop call registered CheckForSignalProc on each loop cycle without blocking user interface and it works. But I do not know if I understand the documentation:

I'm not sure I understand what you did ?

Show quoted text 16 lines
"Sets the function to use to handle polling of file descriptors. It will be used instead of the |poll()| system call (or GLib's replacement function, which is used where |poll()| isn't available). This function could possibly be used to integrate the GLib event loop with an external event loop." "integrate the GLib event loop with an external event loop" - I think this is what I want. My concerns: 1. How does it affect to performance? Is it too often calledfor dbus? 2. Glib is most used by GTK. Will this work when I compile project with QT interface for KDE? (my future plans). I do not want to force users to install whole GTK librarys when they areusing only QT

g_main_context_set_poll_func is only used for the GTK widget set. You'll have to test separately with Qt.

Michael.

Unknown author
to Henry Vermaak

W dniu 13.01.2011 13:40, Henry Vermaak pisze:

Show quoted text 12 lines
On 13/01/11 12:24, wrote: > Did you receive my mail with demo? I think I found temporary solution. Can you send me the source for this, too? Thanks Henry _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Ok. I sent. Please check your mail (gmail account)

I'm wondering if I can use those functionsinstead of g_main_context_set_poll_func. It seems that they are more universal (windows, gtk, qt):
http://wiki.lazarus.freepascal.org/Main_Loop_Hooks The principle of action appears to be very similar, but I don't know what send as Handle: THandle param in DBus case. Without this param it doesn't work.

Matthias Klumpp
to Unknown author: Yes, I even debugged some things, but found no solution yet. I'm not sure I understand…
Show quoted text 15 lines
On Thu, 13 Jan 2011, wrote: > W dniu 10.01.2011 20:41, Michael Van Canneyt pisze: >> >> >> On Mon, 10 Jan 2011, wrote: >> >>> Sorry for refreshing, but the problem is still present :( . It works >>> perfect on my mashine (ubuntu 10.10 64 bit) but doesn't work on my >>> friends >>> computer. For example, one of my friend have this same laptop as me >>> and >>> exactly this same version of ubuntu (64 bit too). My application find >>> signals only when he moving mouse cursor over main form (on idle

event

Show quoted text 17 lines
>>> is >>> fired in which I check for signals too). It looks like method >>> dbus_connection_set_wakeup_main_function doesn't register wake up >>> function >>> properly. This is procedure, not function so I don't even know if >>> there >>> was error. >> >> That can of course be, but this is not under our control. >> >>> I copy source of my program to ubuntu 10.10 32bit on my virtual >>> mashine >>> and compile on latest SVN version of lazarus (like on 64 bit ubuntu). >>> This >>> same problem. I debug this and wake up function is never called in >>> client >>> when dbus host send signals. I have no idea why on 64 bit (and only

on

Show quoted text 23 lines
>>> my) >>> it works ok. Some external library is responsible for this? All >>> computers >>> are upgraded to latest version, so we have this same dbus library. >> >> Do they run the same desktop ? >> >> Can you please provide testprograms (client and server) so I can run >> some >> tests ? >> >> Michael. >> >> _______________________________________________ >> fpc-pascal maillist - >> http://lists.freepascal.org/mailman/listinfo/fpc-pascal >> > Did you receive my mailwith demo? Yes, I even debugged some things, but found no solution yet. > I think I found temporary solution. In > glib2 is procedure:

g_main_context_set_poll_func(g_main_context_default,

Show quoted text 12 lines
> @CheckForSignalProc); > > It seems that application main loop call registered CheckForSignalProc > on > each loop cycle without blocking user interface and it works. But I do > not > know if I understand the documentation: I'm not sure I understand what you did ? > > "Sets the function to use to handle polling of file descriptors. It

will

Show quoted text 23 lines
> be > used instead of the |poll()| system call (or GLib's replacement > function, > which is used where |poll()| isn't available). > > This function could possibly be used to integrate the GLib event loop > with an > external event loop." > > "integrate the GLib event loop with an external event loop" - I think > this is > what I want. > > My concerns: > 1. How does it affect to performance? Is it too often calledfor dbus? > 2. Glib is most used by GTK. Will this work when I compile project with > QT > interface for KDE? (my future plans). I do not want to force users to > install > whole GTK librarys when they areusing only QT g_main_context_set_poll_func is only used for the GTK widget set. You'll have to test separately with Qt.

Hi!
I developed the Listaller Project, a cross-distro Linux software manager, which uses techniques like D-BUS and PolicyKit and had very similar problems. You can run Qt4 applications which use GLib (but only GLib!), but you need to call g_type_init() in the Qt application somewhere to make GObject work. (But only _once_, otherwise you get very strange behavior) This makes the application depend on GLib, but not on GTK+. I won't need my Listaller D-BUS daemon anymore next time, cause the required parts will get merged with the PackageKit project. (D-BUS in Pascal is a PAIN! I wrote a small set of simplifications, but it's far away from a state like C/GLib, where DBus is very easy to use) Projects like PackageKit, PolicyKit or Canberra are the reason why KDE has GLib installed in most times, so depending on GLib and Qt is not really a problem considering the dependencies.
Cheers
Matthias Klumpp

Unknown author
to Henry Vermaak: Can you send me the source for this, too? Thanks Henry

This code work too:

TMyObj = class
private
procedure EventProc(AData: PtrInt; AFlags: dword);
end;
var
Sock: cint;
p: PEventHandler;
const
GLIB_SYSDEF_POLLIN = 1;
GLIB_SYSDEF_POLLOUT = 4;
GLIB_SYSDEF_POLLPRI = 2;
GLIB_SYSDEF_POLLERR = 8;
GLIB_SYSDEF_POLLHUP = 16;
GLIB_SYSDEF_POLLNVAL = 32;
ALL_FLAGS = GLIB_SYSDEF_POLLIN or GLIB_SYSDEF_POLLPRI or
GLIB_SYSDEF_POLLERR or GLIB_SYSDEF_POLLHUP or GLIB_SYSDEF_POLLNVAL;
implementation

{ TMyObj }

procedure TMyObj.EventProc(AData: PtrInt; AFlags: dword);
begin
BusReceive;
end;
....
begin
dbus_connection_get_socket(conn, @Sock);
p := AddEventHandler(Sock, ALL_FLAGS, @EventProc, 0);
end;

But it not detect eachsignal. It lost every third signal. I have no more ideas

Unknown author
to Matthias Klumpp: On Thu, 13 Jan 2011 13:32:29 +0100 (CET), event on…
Matthias Klumpp wrote 13 lines
> g_main_context_set_poll_func is only used for the GTK widget set. > You'll have to test separately with Qt. Hi! I developed the Listaller Project, a cross-distro Linux software manager, which uses techniques like D-BUS and PolicyKit and had very similar problems. You can run Qt4 applications which use GLib (but only GLib!), but you need to call g_type_init() in the Qt application somewhere to make GObject work. (But only _once_, otherwise you get very strange behavior) This makes the application depend on GLib, but not on GTK+. I won't need my Listaller D-BUS daemon anymore next time, cause the required parts will get merged with the PackageKit project. (D-BUS in Pascal is a PAIN! I wrote a small set of simplifications, but it's far away from a state like C/GLib, where DBus is very easy to use)

It's rather easy in my opinon ?
I wrote a set of components that generate pascal code from the DBUS introspection XML, and that works rather nicely. They are not yet published, because I didn't get around to write the server part.

But I must confess that I have not tried using it in a main loop, so the problems experienced here are new to me.

Michael.

Unknown author
to Unknown author: This code work too: TMyObj = class private procedure EventProc(AData: PtrInt; AFlags:…
Show quoted text 36 lines
This code work too: TMyObj = class private procedure EventProc(AData: PtrInt; AFlags: dword); end; var Sock: cint; p: PEventHandler; const GLIB_SYSDEF_POLLIN = 1; GLIB_SYSDEF_POLLOUT = 4; GLIB_SYSDEF_POLLPRI = 2; GLIB_SYSDEF_POLLERR = 8; GLIB_SYSDEF_POLLHUP = 16; GLIB_SYSDEF_POLLNVAL = 32; ALL_FLAGS = GLIB_SYSDEF_POLLIN or GLIB_SYSDEF_POLLPRI or GLIB_SYSDEF_POLLERR or GLIB_SYSDEF_POLLHUP or GLIB_SYSDEF_POLLNVAL; implementation { TMyObj } procedure TMyObj.EventProc(AData: PtrInt; AFlags: dword); begin BusReceive; end; .... begin dbus_connection_get_socket(conn, @Sock); p := AddEventHandler(Sock, ALL_FLAGS, @EventProc, 0); end;

If you refer here to TMyObj.EventProc, then that code is wrong: the stack will get confused. I'm surprised it .

Unknown author
to Matthias Klumpp: On Thu, 13 Jan 2011 13:32:29 +0100 (CET), event on…

W dniu 13.01.2011 14:41, Matthias Klumpp pisze:

Show quoted text 17 lines
Hi! I developed the Listaller Project, a cross-distro Linux software manager, which uses techniques like D-BUS and PolicyKit and had very similar problems. You can run Qt4 applications which use GLib (but only GLib!), but you need to call g_type_init() in the Qt application somewhere to make GObject work. (But only _once_, otherwise you get very strange behavior) This makes the application depend on GLib, but not on GTK+. I won't need my Listaller D-BUS daemon anymore next time, cause the required parts will get merged with the PackageKit project. (D-BUS in Pascal is a PAIN! I wrote a small set of simplifications, but it's far away from a state like C/GLib, where DBus is very easy to use) Projects like PackageKit, PolicyKit or Canberra are the reason why KDE has GLib installed in most times, so depending on GLib and Qt is not really a problem considering the dependencies. Cheers Matthias Klumpp

Thanks for this info Matthias. Simple question:
If I use g_main_context_set_poll_func, does it matter what I return in TGPollFunc? Can this be just 0? Documentation say: "/Returns/ : the number of GPollFD
<http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html#GPollFD> elements which have events or errors reported, or -1 if an error occurred" ... and I don't understand this :P

Regards

Unknown author
to Unknown author: If you refer here to TMyObj.EventProc, then that code is wrong: the stack will get…

W dniu 13.01.2011 15:17, pisze:

Show quoted text 49 lines
On Thu, 13 Jan 2011, wrote: > This code work too: > > TMyObj = class > private > procedure EventProc(AData: PtrInt; AFlags: dword); > end; > > var > Sock: cint; > p: PEventHandler; > > const > GLIB_SYSDEF_POLLIN = 1; > GLIB_SYSDEF_POLLOUT = 4; > GLIB_SYSDEF_POLLPRI = 2; > GLIB_SYSDEF_POLLERR = 8; > GLIB_SYSDEF_POLLHUP = 16; > GLIB_SYSDEF_POLLNVAL = 32; > > ALL_FLAGS = GLIB_SYSDEF_POLLIN or GLIB_SYSDEF_POLLPRI or > GLIB_SYSDEF_POLLERR or GLIB_SYSDEF_POLLHUP or GLIB_SYSDEF_POLLNVAL; > > implementation > > { TMyObj } > > procedure TMyObj.EventProc(AData: PtrInt; AFlags: dword); > begin > BusReceive; > end; > > .... > begin > dbus_connection_get_socket(conn, @Sock); > p := AddEventHandler(Sock, ALL_FLAGS, @EventProc, 0); > end; If you refer here to TMyObj.EventProc, then that code is wrong: the stack will get confused. I'm surprised it compiles at all. Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

This is only example fragment. Of course I refer to the object method by MyObj.EventProc, not to the class. I just wanted to show you how I get socket handle.

Henry Vermaak
to Unknown author: W dniu 10.01.2011 20:41, Michael Van Canneyt pisze: Did you receive my mailwith demo? I…
"integrate the GLib event loop with an external event loop" - I think this is what I want.

What you want to do is to integrate the dbus connection into your main loop (in this case glib). Let me quote from the documentation:

"If you're using GLib or Qt add-on libraries for D-Bus, there are special convenience APIs in those libraries that hide all the details of dispatch and watch/timeout monitoring. For example, dbus_connection_setup_with_g_main().

"If you aren't using these add-on libraries, but want to process messages asynchronously, you must manually call
dbus_connection_set_dispatch_status_function(),
dbus_connection_set_watch_functions(),
dbus_connection_set_timeout_functions() providing appropriate functions to integrate the connection with your application's main loop. This can be tricky to get right; main loops are not simple."

If you look at the dbus_connection_set_watch_functions documentation:

http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#gaebf031eb444b4f847606aa27daa3d8e6

You'll see that this will provide you will file descriptors that you can add to your main loop to watch for the dbus events.

This is all _much_ simpler if you use the dbus-glib functions:

http://www.ibm.com/developerworks/linux/library/l-dbus.html

It doesn't look like that header has been translated to pascal, yet. That doesn't matter, since it's now considered obsolete, since glib has dbus support now:

http://www.freedesktop.org/wiki/Software/DBusBindings

fpc doesn't seem to have bindings for that, either...

Henry

Henry Vermaak
to Henry Vermaak
Henry Vermaak wrote 40 lines
On 13/01/11 12:24, wrote: > > "integrate the GLib event loop with an external event loop" - I think > this is what I want. What you want to do is to integrate the dbus connection into your main loop (in this case glib). Let me quote from the documentation: "If you're using GLib or Qt add-on libraries for D-Bus, there are special convenience APIs in those libraries that hide all the details of dispatch and watch/timeout monitoring. For example, dbus_connection_setup_with_g_main(). "If you aren't using these add-on libraries, but want to process messages asynchronously, you must manually call dbus_connection_set_dispatch_status_function(), dbus_connection_set_watch_functions(), dbus_connection_set_timeout_functions() providing appropriate functions to integrate the connection with your application's main loop. This can be tricky to get right; main loops are not simple." If you look at the dbus_connection_set_watch_functions documentation: http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#gaebf031eb444b4f847606aa27daa3d8e6 You'll see that this will provide you will file descriptors that you can add to your main loop to watch for the dbus events. This is all _much_ simpler if you use the dbus-glib functions: http://www.ibm.com/developerworks/linux/library/l-dbus.html It doesn't look like that header has been translated to pascal, yet. That doesn't matter, since it's now considered obsolete, since glib has dbus support now: http://www.freedesktop.org/wiki/Software/DBusBindings fpc doesn't seem to have bindings for that, either...

Having said all of this, you can get around this by calling blocking dbus calls in a thread and notifying the user interface by virtue of Synchronize, PostMessage and QueueAsycCall.

Henry

Matthias Klumpp
to Unknown author: W dniu 13.01.2011 14:41, Matthias Klumpp pisze: Thanks for this info Matthias. Simple…
W dniu 13.01.2011 14:41, Matthias Klumpp pisze: > Hi! > I developed the Listaller Project, a cross-distro Linux software

manager,

Show quoted text 5 lines
> which uses techniques like D-BUS and PolicyKit and had very similar > problems. You can run Qt4 applications which use GLib (but only GLib!), > but > you need to call g_type_init() in the Qt application somewhere to make > GObject work. (But only _once_, otherwise you get very strange

behavior)

> This makes the application depend on GLib, but not on GTK+. I won't

need

> my > Listaller D-BUS daemon anymore next time, cause the required parts will > get > merged with the PackageKit project. (D-BUS in Pascal is a PAIN! I wrote

a

> small set of simplifications, but it's far away from a state like

C/GLib,

Show quoted text 12 lines
> where DBus is very easy to use) Projects like PackageKit, PolicyKit or > Canberra are the reason why KDE has GLib installed in most times, so > depending on GLib and Qt is not really a problem considering the > dependencies. > Cheers > Matthias Klumpp > Thanks for this info Matthias. Simple question: If I use g_main_context_set_poll_func, does it matter what I return in TGPollFunc? Can this be just 0? Documentation say: "/Returns/ : the number of GPollFD

<http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html#GPollFD>

elements which have events or errors reported, or -1 if an error

occurred"

... and I don't understand this :P

Hi!
Very simple: You just return the number of GPollFD records which have failed (G_IO_ERR). If everything is fine, you return 0. For any other error which makes this function fail, you return -1
(But I must admit I never used this directly)
It is so great seeing someone building DBus bindings for Pascal! I requested this years ago, and finally it happens! (There are great use-cases for this, even if I won't use it in Listaller directly anymore) Regards
Matthias

Unknown author
to Henry Vermaak: Having said all of this, you can get around this by calling blocking dbus calls in a…

W dniu 13.01.2011 16:02, Henry Vermaak pisze:

Show quoted text 52 lines
On 13/01/11 15:00, Henry Vermaak wrote: > On 13/01/11 12:24, wrote: >> >> "integrate the GLib event loop with an external event loop" - I think >> this is what I want. > > What you want to do is to integrate the dbus connection into your main > loop (in this case glib). Let me quote from the documentation: > > "If you're using GLib or Qt add-on libraries for D-Bus, there are > special convenience APIs in those libraries that hide all the details of > dispatch and watch/timeout monitoring. For example, > dbus_connection_setup_with_g_main(). > > "If you aren't using these add-on libraries, but want to process > messages asynchronously, you must manually call > dbus_connection_set_dispatch_status_function(), > dbus_connection_set_watch_functions(), > dbus_connection_set_timeout_functions() providing appropriate functions > to integrate the connection with your application's main loop. This can > be tricky to get right; main loops are not simple." > > If you look at the dbus_connection_set_watch_functions documentation: > > http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#gaebf031eb444b4f847606aa27daa3d8e6 > > > > You'll see that this will provide you will file descriptors that you can > add to your main loop to watch for the dbus events. > > This is all _much_ simpler if you use the dbus-glib functions: > > http://www.ibm.com/developerworks/linux/library/l-dbus.html > > It doesn't look like that header has been translated to pascal, yet. > That doesn't matter, since it's now considered obsolete, since glib has > dbus support now: > > http://www.freedesktop.org/wiki/Software/DBusBindings > > fpc doesn't seem to have bindings for that, either... Having said all of this, you can get around this by calling blocking dbus calls in a thread and notifying the user interface by virtue of Synchronize, PostMessage and QueueAsycCall. Henry _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

I'm trying with "dbus_connection_set_watch_functions" but this is not easy like it look. I thought that I must only register my event procedures by calling this functions but there is much more work. I have a headache. Now I understand why dbus documentation begins with the words "If you use this low-level API directly, you're signing up for some pain" ;) . Tomorrow I look for some "live example" of using this functions in C.

I tried with thread. It doesn't catch all signals even if I call sleep(1) in loop. I don't know what is reason of this loss. Thread and AddEventHandler have this same problem - they don't catch all signals. Only one way which works is "g_main_context_set_poll_func" but now I see that the application consumes 30% CPU. So now I understand why it catch all signals. @**Matthias how you solved problem with CPU and this function?

This all problems started after this upgrade (probably): http://bugs.freepascal.org/view.php?id=14086
Because before I listened for signals in thread with sleep(100) without problems.

P.S. People who have demo from me, please comment line: dbus_connection_close(conn);
in my_client_app -> busexample.pas
This should not be there.

Henry Vermaak
to Unknown author
Show quoted text 7 lines
I'm trying with "dbus_connection_set_watch_functions" but this is not easy like it look. I thought that I must only register my event procedures by calling this functions but there is much more work. I have a headache. Now I understand why dbus documentation begins with the words "If you use this low-level API directly, you're signing up for some pain" ;) . Tomorrow I look for some "live example" of using this functions in C.

Indeed, it's pretty ugly.

Show quoted text 6 lines
I tried with thread. It doesn't catch all signals even if I call sleep(1) in loop. I don't know what is reason of this loss. Thread and AddEventHandler have this same problem - they don't catch all signals. Only one way which works is "g_main_context_set_poll_func" but now I see that the application consumes 30% CPU. So now I understand why it catch all signals. @Matthias how you solved problem with CPU and this function?

I changed your code to run in a thread and it works well for me. I made a thread safe TQueue derivative that I add messages to, then I notify the gui thread with PostMessage. The gui thread pops the messages from the queue and displays them. This works even if I add huge delays in the gui thread, since the queue is a buffer. This solution should also work with other widgetsets.

I'll send you some code tomorrow (it's on my work computer).

Henry

Unknown author
to Henry Vermaak

W dniu 13.01.2011 21:12, Henry Vermaak pisze:

Show quoted text 29 lines
On 13 January 2011 19:51, wrote: > I'm trying with "dbus_connection_set_watch_functions" but this is not easy > like it look. I thought that I must only register my event procedures by > calling this functions but there is much more work. I have a headache. Now I > understand why dbus documentation begins with the words "If you use this > low-level API directly, you're signing up for some pain" ;) . Tomorrow I > look for some "live example" of using this functions in C. Indeed, it's pretty ugly. > I tried with thread. It doesn't catch all signals even if I call sleep(1) in > loop. I don't know what is reason of this loss. Thread and AddEventHandler > have this same problem - they don't catch all signals. Only one way which > works is "g_main_context_set_poll_func" but now I see that the application > consumes 30% CPU. So now I understand why it catch all signals. @Matthias > how you solved problem with CPU and this function? I changed your code to run in a thread and it works well for me. I made a thread safe TQueue derivative that I add messages to, then I notify the gui thread with PostMessage. The gui thread pops the messages from the queue and displays them. This works even if I add huge delays in the gui thread, since the queue is a buffer. This solution should also work with other widgetsets. I'll send you some code tomorrow (it's on my work computer). Henry _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Thanks. I'm waiting.

Unknown author
to Henry Vermaak: Indeed, it's pretty ugly. I changed your code to run in a thread and it works well for…

W dniu 13.01.2011 21:12, Henry Vermaak pisze:

Show quoted text 28 lines
On 13 January 2011 19:51, wrote: > I'm trying with "dbus_connection_set_watch_functions" but this is not easy > like it look. I thought that I must only register my event procedures by > calling this functions but there is much more work. I have a headache. Now I > understand why dbus documentation begins with the words "If you use this > low-level API directly, you're signing up for some pain" ;) . Tomorrow I > look for some "live example" of using this functions in C. Indeed, it's pretty ugly. > I tried with thread. It doesn't catch all signals even if I call sleep(1) in > loop. I don't know what is reason of this loss. Thread and AddEventHandler > have this same problem - they don't catch all signals. Only one way which > works is "g_main_context_set_poll_func" but now I see that the application > consumes 30% CPU. So now I understand why it catch all signals. @Matthias > how you solved problem with CPU and this function? I changed your code to run in a thread and it works well for me. I made a thread safe TQueue derivative that I add messages to, then I notify the gui thread with PostMessage. The gui thread pops the messages from the queue and displays them. This works even if I add huge delays in the gui thread, since the queue is a buffer. This solution should also work with other widgetsets. I'll send you some code tomorrow (it's on my work computer). Henry _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Ok, I found reason by analyzing your demo. My threads were not different from yours (except PostMessage - I am using Synchronize). I could not find the place where you call Sleep to reduce CPU usage by thread loop. Then I found this line:
dbus_connection_read_write(conn, 100);
And this is solution. I used 0 timeout (involuntarily, I just copy and paste from console demo). It seems that for the console version is sufficient time, but not enough for GUI application listening in threads. So I can use this timeout to reduce CPU usage instead of standard Sleep(100). Additionally, thistimeout catch all "lost" signals. So now I get 100% of sent signals. After this modification, my programs based on threads started working again.
Of course, problem with "dbus_connection_set_wakeup_main_function" and "dbus_connection_set_watch_functions" still exists. But now when threads working again, I can live with that. If you don't have what you like, then you like what you have ;)

Thank you all for your invaluable help.
Regards. Dibo.

Unknown author
to Henry Vermaak: Indeed, it's pretty ugly. I changed your code to run in a thread and it works well for…

I found another way to register own callback events (this is example which connect to Pidgin instant messenger):

var
VTable: DBusObjectPathVTable;
function MessageHandler(connection: PDBusConnection; message_: PDBusMessage;
user_data: Pointer): DBusHandlerResult; cdecl;
begin
MemoLog.Lines.Add('New signal');
Result := DBUS_HANDLER_RESULT_HANDLED;
end;
function BusConnect: Boolean;
begin
Result := False;
dbus_error_init(@err);
MemoLog.Lines.Add('Listening for signals');
{ Connection }
conn := dbus_bus_get(DBUS_BUS_SESSION, @err);
if dbus_error_is_set(@err)  0 then
begin
WriteLn('Connection Error: ' + err.message);
dbus_error_free(@err);
end;
{ Request the name of the bus }
ret := dbus_bus_request_name(conn, 'im.pidgin.purple.PurpleInterface',
DBUS_NAME_FLAG_REPLACE_EXISTING, @err);
if dbus_error_is_set(@err)  0 then
begin
MemoLog.Lines.Add('Name Error: ' + err.message);
dbus_error_free(@err);
Exit;
end;
// add a rule for which messages we want to see
dbus_bus_add_match(conn,
'type=''signal'',interface=''im.pidgin.purple.PurpleInterface''', @err);
// see signals from the given interface
dbus_connection_flush(conn);
if (dbus_error_is_set(@err)  0) then
begin
MemoLog.Lines.Add('Match Error (' + err.message + ')');
Exit;
end;
MemoLog.Lines.Add('Match rule sent');
VTable.message_function := @MessageHandler;
if dbus_connection_try_register_object_path(conn,
'/im/pidgin/purple/PurpleObject', @VTable, nil, @err)=0 then
MemoLog.Lines.Add('Cant register');
if (dbus_error_is_set(@err)  0) then
begin
MemoLog.Lines.Add('Error in register (' + err.message + ')');
Exit;
end;
Result := True;
end;

But this same problem like with dbus_connection_set_wakeup_main_function
- It works only on my computer (64 bit ubuntu). When I send this executable to my friends or compile and run on 32 bit ubuntu, then MessageHandler is never called. dbus_connection_try_register_object_path return TRUE and error is not set, so I don't know what is a reason. But this is another proof that something is wrong with receiving callback events by free pascal dbus. I have no idea what blocking this on other computers. Firewall? Missing some librarys? On each computer is same libdbus library.