Re: Synchronous method in asynchronous signal callback

Thomas Downing <[email protected]>
Newsgroups gmane.comp.freedesktop.dbus
Organization Bomgar
Message-ID <[email protected]>
Simon has given some good advice, to which I add, a great rule for working 
with libdbus is _never_ make any calls to libdbus from any thread if 
dbus_connection_dispatch is in the call stack of any thread.

Like any rule there are exceptions, such as dbus_message_ref and _unref.

With this, using the asynchronous dbus_connection_send pretty straight 
forward.  Switching to the asynchronous send of method calls shouldn't be that 
hard, you have an event loop no?

So, pseudo code _might_ look like:

main_loop
	epoll_wait on dbus_watches and my_event
	if dbus_watch
		do dispatch
	if my event
		if receive_queue has messages
			for each message
				invoke_method( messages )
		if send_queue has messages
			for each message
				send message

filter_func
	if is signal A or reply to my method call
		dbus_message_ref signal
		push onto receive queue
		write my_event

invoke_method
	if signal A
		push my_method_call onto send_queue
		write my_event
	if reply to my method call
		use_reply
	dbus_message_unref signal or reply
		


On Thursday, May 14, 2015 10:16:05 Marco Bascetta wrote:
> Hello,
> 
> I'm using libdbus with a poll mainloop. I monitor the DBusWatch file
> descriptor to call "dbus_watch_handle" and "dbus_connection_dispatch".
> Also, I add a connection filter to handle asynchronous signals (only
> DBUS_MESSAGE_TYPE_SIGNAL messages).
> 
> When an event occurs, a callback is called and a specified method is
> performed throught "dbus_connection_send_with_reply_and_block" and a
> flag is set in order to indicates that the dispatch function must run
> another time.
> 
> This is an example of the code
> [pseudocode]
> init_func()
> {
>      dbus_threads_init_default()
>      conn = dbus_bus_get(...)
>      dbus_connection_set_watch_functions(conn, ...)               # This
> store watch_fd in poll
>      dbus_connection_add_filter(conn, filter_func, ...)
> }
> 
> invoke_method()
> {
>      dbus_connection_send_with_reply_and_block(conn, ...)
>      use_reply()
>      flag_set(force_dispatch)
> }
> 
> filter_func()
> {
>      if( dbus_message_get_type(...) == DBUS_MESSAGE_TYPE_SIGNAL ) {
>          if( is(signal_A) ) {
>              invoke_method()
>          } else {
>              do_other_things()
>          }
>      }
> }
> 
> # This is called when watch_fd
> dispach_func()
> {
>          do {
>              flag_unset(force_dispatch)
> 
>              dbus_watch_handle(dbus_watch,
> dbus_watch_get_flags(dbus_watch));
> 
>              while (dbus_connection_get_dispatch_status(conn) ==
> DBUS_DISPATCH_DATA_REMAINS) {
>                  dbus_connection_dispatch(conn);
>              }
> 
>          } while( flag_is_set(force_dispatch) );
> }
> [pseudocode]
> 
> It works without deadlock or message missing, but the signals received
> during the "invoke_method" are delayed until another signal is received
> (watch fd unlocks the poll) (and this could occurs much later...)
> 
> Could you suggest me how to resolve this issue without using the
> asynchronous calls only?
> 
> Thanks
> 
> Best regards
_______________________________________________
dbus mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dbus
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.