Re: Some comments about GVFS



On Tue, 2007-05-08 at 09:30 +0200, Alexander Larsson wrote:
> On Mon, 2007-05-07 at 14:08 -0500, Hans Petter Jansson wrote:

> > In Flow, I keep a GMainContext associated with each GThread. The API
> > user can set his own GMainContext for each thread, but for simplicity it
> > can only be set once, before any other Flow calls are made in that
> > thread.

> So, an async operation inherits the main context from the thread that
> started it. Its nice that you don't have to fill up the API with context
> arguments, but it also seems to make it a bit more complicated to handle
> multiple contexts. For instance, you can't have one thread starting
> async operations that run on multiple context. But perhaps this is not
> so important? What do users of multiple contexts need?

Being able to provide a different main context on each call is extremely
flexible, but in the end I doubt it is necessary in the majority of
apps, and as you pointed out, it clutters the code.

The main reason I have the main-context-per-thread is that a Flow
pipeline won't run without a main context - for instance, elements can
limit flow rate by installing a timeout and resuming when it fires, or
otherwise generate timed events. And applications will definitely want
to run pipelines in threads.

I'm used to three main design patterns:

1) Everything in one thread with sync I/O blocking the UI. Simple code
but unacceptable performance.

2) Everything in one thread with async I/O using callbacks. Fine for
simple protocols or if you prefer an explicit state machine.

3) Doing synchronous I/O operations in one or more subthreads that talk
to the main thread using asynchronous messages queues. This is nice for
complex protocol implementations, because synchronous code is easier to
understand and maintain.

All of the above can be done with I/O dispatched in a single
GMainContext per thread. 1) is a special case where you could have one
GMainContext for the UI and another for the I/O.

That said, it'd be interesting to know if anyone runs multiple main
contexts in a single thread and needs to dispatch I/O events in more
than one of those. It sounds rather contrived to me...

> > I find that this allows for a lot of flexibility without adding much
> > code complexity at all:
> > 
> > 1) The default GMainContext for the main thread is the default GLib
> > GMainContext. This allows sync operations to spin the main loop (so if
> > you have a program that lends itself to that design, you can process
> > redraws and UI operations while in a sync I/O call).

> Danger will robinson! This sounds like a recipe for disaster. Sync calls
> calling back into the mainloop can easily cause reentrancy, and we're
> back in bonobo hell again. I.E. call any flow function, and you could
> reenter (via a mainloop callback) into any random code in the app which
> could modify the state of the code that was calling flow. (And if that
> state is in a partially changed state things can go very bad.)
> 
> Its also very problematic wrt locking. We have the same problem with
> authentication callbacks in gnome-vfs. These are called back from any
> sync operation when authentication is needed, and often requires UI to
> finish, and thus a mainloop. However, since it is doing UI it needs to
> take the gdk lock, but that deadlocks if the gdk lock was taken when the
> sync call was called. In the case of flow, what if you get an idle
> callback inside a sync call, and the idle callback (correctly) takes the
> gdk lock...

I'm aware of the dangers - when I worked on Evolution, this caused
plenty of pain.

However, it's useful in very simple apps where you have e.g. a "Sync" or
"Connect" button which desensitizes most of the UI while the operation
is in progress, only updating a progress bar or allowing the user to hit
"Cancel". That's what I meant by a "program that lends itself to that
design" above :)

So I dunno. Maybe it's too seductive and should be eliminated as an
option.

-- 
Hans Petter




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