Re: Asyncronous life helper (Was: EggDBus)



On Sat, 2008-12-27 at 15:19 -0500, David Zeuthen wrote:

>  GFuture *future;
>  future = g_future_get (foo->pending_call);
>  g_object_set_data (future, "other-stuff", other_stuff, g_object_unref);
>
> and the GFuture object would be unreffed when the pending call is
> finished.

I'd like to avoid having the data be separately allocated, that lets us
get rid of at least one separate free call/destroy notify. 

> > One major problem about doing things like this in C is that you
> > constantly have to define and allocate small structs to keep the data
> > you need for the completo operation. If we could somehow make this
> > easier that would be a large win. I don't know a great approach to do
> > that offhand though. Some form of user data is one possibility, but I'd
> > really like it to betype safe and without using strings as API.
> 
> If you want type safety you could subclass GFuture and do this
> 
>  subclassed_future = my_subclassed_future_new (...);
>  g_future_set (foo->pending_call, G_FUTURE (subclassed_future));
> 
> but for simple stuff we can have convenience stuff on GFuture just like
> we do for GSimpleAsyncResult.

subclassing is just to much overhead to do per async call. You generally
have lots of async calls in a single sourcecode file, and you can't
realistically use a separate gobject class for each. However, you can
probably define a small struct for each and somehow make a generic
future object contain such a struct.

> > I guess a GFuture/GWish needs to be some form of container that you can
> > grow in size by adding a struct of your own data to it. Maybe we can do
> > it via a macro g_future_push_struct (future, struct LocalOpData,
> > free_op_data) which grows the size of the object and puts the struct at
> > the end. You'll pop it at end to free it.
> > 
> > Of course, such serial/stack-like data management might not be general
> > enought to handle things like parallel async operations. Maybe just a
> > way to add the struct (undefined where) to the GFuture and then you'll
> > get a pointer to the struct inside the GFuture in the completion
> > callback...
> 
> I think a lot of this would be simpler with fibers....

continuations, fibers, threads, etc *vastly* simplify many cases of
async operations. However, they don't express the full solution-space of
async ops. For a simple example, take the sftp gvfs backend, which is
fully async. The get_info() operation does both a stat and an lstat in
parallel and returns when both are completed or on the first error. If
you serialized this via a fiber you'd double the network latency of the
get_info() call. 

Another example is a "perfect" network data copy operation. You need to
keep scheduling both download and upload in parallel so that you always
have data to send. 

So, I think there is a place for a true GFuture-style machinery, even if
you have something like fibers availible. Of course, you'd like them to
be API compatible so that you can use a fiber as a GFuture. For
instance, you might want to express a dependency of your GFuture be the
result from some fiber operation.



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