On 27 August 2015 at 17:33, Frederik Lotter <frederik.lot...@gmail.com> wrote:
> On 26 August 2015 at 12:13, Frederik Lotter <frederik.lot...@gmail.com> > wrote: > >> Hi, >> >> I am very new to GLIB so please excuse me if I made any stupid >> assumptions... >> >> I did a lot of reading and testing my understanding but I feel a bit >> stuck. I feel like I am missing something obvious, or trying to use GLIB in >> the wrong way. >> >> I am using GLIB in my applications (consisting of 3 separate processes) >> originally because I need DBUS access to Ofono and Connman (and between >> each other to implement shared variables) on our embedded Linux >> environment. >> >> (1) The first issue came when I realised that making synchronous DBUS >> calls between processes can result in a deadlock when two processes make >> DBUS requests to each other each waiting for the synchronous call to >> complete, which is preventing the GLIB event loop from servicing the DBUS >> request. >> >> generated_com_mixtelematics_parameters_call_get_parameter_sync(..) >> >> => >> >> generated_com_mixtelematics_parameters_call_get_parameter(..) >> >> I changed all the DBUS calls to use the asynchronous calls. >> >> (2) The second issue came when I realized our application framework >> requires synchronous calls mapping to the underlying asynchronous GLIB >> requests, so I implemented wrapper functions which waits on an >> async_queue_pop() to wait for the result, before returning to the caller. >> >> // Async >> generated_com_mixtelematics_parameters_call_get_parameter(..) >> >> g_async_queue_pop(callbackParameters.semaphore); >> >> However, this introduced another issue. If this synchronous wrapper is >> called from the GLIB main context thread, it would deadlock. The blocking >> call to pop() would not release the event loop to service the async DBUS >> call. >> >> (3) This is where I am getting stuck chasing my own tail ... >> >> The problem is I would like the API call to be possible _from_ the GLIB >> event thread, but also _outside_ from another thread. The case in (2) only >> works from outside threads. >> >> So I added this (please do not shoot me): >> >> while(g_async_queue_try_pop(context.semaphore) == NULL) >> { >> g_main_context_iteration(NULL,TRUE/FALSE); >> } >> >> (A) It seems like this call can not work from outside the GLIB event >> thread. >> >> (B) If I call it work TRUE=blocking, it gets stuck in an outside thread >> >> (C) If I call it with FALSE=non blocking, it spins >> >> So it looks like I am going down the wrong path here. In the event thread >> it would work, and in an outside thread I need to use (2). >> >> Any hints would me very much appreciated. >> >> Kind Regards, >> Frederik Lotter >> >> MiX Telematics >> South Africa >> > > > I think I am now heading in a better direction, but would be very grateful > if someone could give me a hint. > > I am working with: > > g_main_context_push_thread_default() and > g_main_context_pop_thread_default(). > > The main aim for me is to have the ability to make an ASYNC call, which is > currently being called inside thread-default context X, have it's callback > handled in thread-default context Y. > > Example: > > (A) DBUS incoming calls (server thread) handled in thread-default context > X (TID=0x01) > (B) DBUS incoming call makes ASYNC call (DBUS outgoing call), with > callback handled in thread-default context Y (TID=0x02) > > In order to have ASYNC calls made from TID=0x01 direct their callbacks to > TID=0x02, the thread-default context must be set in TID=0x01 > > The issue: > > (1) For incoming calls I can register the source on a default context > before starting the main loop g_main_loop_run(). This works. > > (2) However, for ASYNC calls that happens during the lifetime of the > g_main_loop_run() used in (A) above, it seems > g_main_context_push_thread_default() and > g_main_context_pop_thread_default() around the main loop in (A) keeps the > context locked and prevents dispatching from the second loop running in > TID=0x02. > > g_main_context_push_thread_default(Y); > > g_main_loop_run(X); > > g_main_context_pop_thread_default(Y); > > Only after the pop is made will the other thread process the events which > got added during the lifetime of the main loop above. > > (3) If the push and pop is made around the ASYNC function call: > > g_main_context_push_thread_default(Y); > > g_dbus_connection_call(...) // ASYNC with callback > > g_main_context_pop_thread_default(Y); > > The push fails to acquire the context because the main loop running > context (Y) is already in action and locking the context. > > So I think my question is: How can I, at runtime, direct an ASYNC callback > to a custom context (Y) when the ASYNC call is made inside code that was > invoked by the GLIB main loop in the first place (from another context X). > > Kind Regards, > Frederik Lotter > > I have formulated my question differently with a working example on stackoverflow: http://stackoverflow.com/questions/32266645/how-do-i-use-the-glib-function-g-main-context-push-thread-default-pop-correctl
_______________________________________________ gtk-list mailing list gtk-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-list