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

Reply via email to