[fprint] Problem with g_main_loop_run libfprint v1.90.7

Benjamin Berg benjamin at sipsolutions.net
Wed Apr 14 17:21:10 UTC 2021


Hi,

On Wed, 2021-04-14 at 16:04 +0000, Carlos Garcia wrote:
>  
> Hi everyone.
>  
> I have problems with g_main_loop_runexecuting it in another thread.
> I’m using  a Digital Persona U are U 4500 device.
> 
If you have the g_main_loop_run running in a different thread, then
*all* calls into libfprint must be coming from that same thread.
libfprint is not threadsafe, and running the mainloop in one thread
while doing calls from another one must not happen.

If you need to run a thread in order to execute the GLib mainloop, then
you should do all calls through that thread. One of the easiest ways to
do this is to use g_idle_add in order to execute a function in the
right thread that can then freely use libfprint APIs.

Another caveat that you may run into is that libfprint is a bit buggy
about the main context it uses if you use the _sync routines (It runs
the global default main context recursively, but the internal GTasks
are attached to the thread local main context. Technically a bug, but
it is irrelevant in most cases).
The easiest way of making sure it works is probably to just stick to
always use the default main context rather than creating a new one
(just pass NULL to g_main_loop_new).

I hope this helps,
Benjamin

> I have an init function that opens a device, when the device is
> opened, theng_main_loop_run is execute in another thread.
> When I close the device calling fp_device_close_sync  the result is
> TRUE but I have the following error:
>  
> (process:38166): libfprint-image_device-
> DEBUG: 10:56:02.418: Image device close completed
> (process:38166): libfprint-device-
> DEBUG: 10:56:02.418: Device reported close completion
> (process:38166): libfprint-device-
> DEBUG: 10:56:02.418: Completing action FPI_DEVICE_ACTION_CLOSE in idl
> e!
>  
> (process:38166): GLib-
> CRITICAL **: 10:56:02.418: g_source_unref: assertion 'source != NULL'
>  failed
>  
>  
> The documentation for  fp_device_close_sync  says that the return
> value is:FALSE on error,TRUE otherwise. So, if the function returns
> TRUE why this error?
>  
> Another problem is that sometimes calling fp_device_close_sync
> freezes the app becausefp_device_close_sync never returns.
>  
> Here is my code:
>  
>  
> typedef struct
> {
>     FpContext *ctx;             ///< Libfprint context.
>     FpDevice *device;           ///< Libfprint device.
>     pthread_t event_t;          ///< The glib event loop thread.
>     GMainLoop *gmloop;          ///< Glib event manager loop.
> }tETR_FP_CONTEXT;
>  
> typedef struct
> {
>     tKERNEL_FSM *fsm;           ///< Finite State Machine structure p
> ointer.
>     tETR_FP_CONTEXT ctx;        ///< Fingerprint context structure.
> }tAUTOMATON_DATA;
>  
> static void * etr_fp_execute_loop(void *data)
> {
>     tAUTOMATON_DATA *aut = (tAUTOMATON_DATA *) data;
>  
>     aut->ctx.gmloop = g_main_loop_new(NULL,FALSE);
>     g_main_loop_run(aut->ctx.gmloop);
>  
>     return NULL;
> }
>  
> void init__entry(tAUTOMATON_DATA *aut)
> {
>     FpDevice *device;
>     GPtrArray *devices;
>     g_autoptr(GError) gerror = NULL;
>  
>     aut->ctx.ctx = fp_context_new();
>     devices      = fp_context_get_devices(aut->ctx.ctx);
>  
>     if (devices && devices->len)
>     {
>         device = g_ptr_array_index(devices,0);
>         aut->ctx.device = device;
>  
>         // Open device
>         if (fp_device_open_sync(aut->ctx.device,aut-
> >ctx.clops,&gerror))  
>         {
>             // Execute g_main_loop_run in another thread
>             if (!pthread_create(&aut-
> >ctx.event_t,NULL,&etr_fp_execute_loop,aut)) {
>                 pthread_detach(aut->ctx.event_t);
>                 KernelInsertEvent(aut->fsm-
> >aut_id,AUT_EVT_OPENED,NULL,0);
>             }
>             else
>                 LogError("Unable to create glib event loop thread");
>         }
>         else
>             LogError("Unable to open device. %s",gerror->message);
>     }
>     else LogError("Unable to find a compatible device");
> }
>  
> static void etr_fp_dev_close(tAUTOMATON_DATA *aut)
> {
>     g_autoptr(GError) gerror = NULL;
>  
>     if (!fp_device_close_sync(aut-
> >ctx.device,NULL,&gerror)) // Sometimes calling this function 
>     {                                                       
> // freezes the app. Because never returns.  
>         LogError("Error closing device: %s",gerror->message);
>     }
>  
>     g_clear_object(&aut->ctx.ctx);
>     g_clear_object(&aut->ctx.clops);
>  
>     if (aut->ctx.gmloop != NULL) {
>         g_main_loop_quit(aut->ctx.gmloop);
>         g_main_loop_unref(aut->ctx.gmloop);
>     }
> }
>  
> If I create a new context with g_main_context_new and apply
> tog_main_loop_newas follows:
>  
> new_context = g_main_context_new();
> aut->ctx.gmloop = g_main_loop_new(new_context, false);
>  
> and use the follow functions in the thread function:
>  
> static void * etr_fp_execute_loop(void *data)
> {
>        tAUTOMATON_DATA *aut = (tAUTOMATON_DATA *) data;
>  
>        g_main_context_push_thread_default(new_context);
>        g_main_loop_run(aut->ctx.gmloop);
>        g_main_context_pop_thread_default(new_context);
>  
>        return NULL;
> }
>  
> Nothing works. 
>  
> Hope someone can help me. Thank you all.
>  
> _______________________________________________
> fprint mailing list
> fprint at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/fprint

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <https://lists.freedesktop.org/archives/fprint/attachments/20210414/4d58df5a/attachment.sig>


More information about the fprint mailing list