Re: [PATCH 3/3] rpc: Rework rpc notifications in main and side thread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Dec 18, 2023 at 10:32:07AM +0000, Daniel P. Berrangé wrote:
> On Fri, Dec 15, 2023 at 02:32:19AM +0800, Fima Shevrin wrote:
> > RPC client implementation uses the following paradigm. The critical
> > section is organized via virObjectLock(client)/virObjectUnlock(client)
> > braces. Though this is potentially problematic as
> >     main thread:                            side thread:
> >     virObjectUnlock(client);
> >                                         virObjectLock(client);
> >                                         g_main_loop_quit(client->eventLoop);
> >                                         virObjectUnlock(client);
> >     g_main_loop_run(client->eventLoop);
> > 
> > This means in particular that is the main thread is executing very long
> > request like VM migration, the wakeup from the side thread could be
> > stuck until the main request will be fully completed.
> 
> Ah, I understand this now. The flag set from g_main_loop_quit() is
> ignored and overwritten by g_main_loop_run(). So the interruption
> from the side thread never happens.
> 
> Your approach to solving this is by delaying the virObjectUnlock
> call until g_main_loop_run is running, which is clever but I don't
> much like playing games with the mutex locking.
> 
> We need a way to interrupt the main loop, even if it hasn't started
> running yet. The previous impl in libvirt used a pipe for this trick,
> effectively as a dummy event source that would be watched.
> 
> I think we can do the same here, though without needing an actual
> pipe which causes Windows portability problems.
> 
> Glib already has an internal mechansim for breaking out of poll(),
> via its (private) GWakeup object which encapsulates a pipe. We just
> need a way of triggering this mechanism.
> 
> I believe this can be achieved using just an idle source ie
> 
> static gboolean
> dummy_cb(void *opaque)
> {

Opps, would still need a  g_main_loop_quit() call here 

>     return G_SOURCE_REMOVE;
> }
> 
> ...
> 
>    GSource *dummy = g_idle_source_new()
>    g_source_set_callback(dummy, dummy_cb, NULL, NULL);
>    g_source_attach(dummy, client->eventCtx);
> 
> 
> The g_source_attach() method is what breaks the main loop out of
> its poll() sleep. If it wasn't currently in poll, it is effectively
> a no-op.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux