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
_______________________________________________ gtk-list mailing list gtk-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-list