Re: (*prepare) and (*check) need user_data



On 27 Mar 1999, Owen Taylor wrote:

> 
> Tim Janik <timj@gtk.org> writes:
> 
> > On 23 Mar 1999, Owen Taylor wrote:
> > 
> > > 
> > > Tim Janik <timj@gtk.org> writes:
> > > 
> > > > hi owen,
> > > > 
> > > > i discovered that for most applications of GSource in conjunction
> > > > with a poll fd, you'd want to add the pollfd right away with the source
> > > > and remove it again, like:
> > > > 
> > > > static void
> > > > destroy_poll_fd (gpointer data)
> > > > {
> > > >   GPollFD *pfd = data;
> > > > 
> > > >   g_main_remove_poll (pfd);
> > > >   g_free (pfd);
> > > > }
> > > > 
> > > > 
> > > >   pfd = g_new0 (GPollFD, 1);
> > > >   pfd->fd = some_fd;
> > > >   pfd->events |= G_IO_IN | G_IO_OUT | G_IO_PRI;
> > > >   g_main_add_poll (pfd, X_PRIORITY);
> > > >   g_source_add (X_PRIORITY, TRUE, &x_funcs, x, pfd, destroy_poll_fd);
> > > > 
> > > > to properly make use of the pollfd in prepare and check, the user_data pointer
> > > > needs to be provided though, this can be achived while keeping binary
> > > > compatibility with 1.2.0.
> > > 
> > > OK, I don't understand this at all. The user data  pointer
> > > is only used to dispatch the call back to the user..
> > > 
> > > This should only be done in the dispatch functtion, or
> > > you're breaking the model...
> > 
> > nope, i'm not breaking the model. i just use sources differently from the
> > way e.g. timeouts or idles work. that is, i'm not using source_data for a function
> > pointer and user_data as an argument to dispatch that function, rather i'm passing
> > an object in as source_data and use user_data for a GPollFd*.
> > 
> > in (*prepare), i'm adjusting the GPollFD.events field acccording to the object's
> > state.
> > 
> > in (*check), i'm evaluating the object state again *and* GPollFD.revents, and from
> > that, i figure whether dispatching is required.
> > 
> > finally, (*dispatch) amounts to something as simple as object->dispatch().
> > 
> > what the above example meant to show is that user_data is extremely convenient
> > to hold GPollFDs for fds that have the same life time as their corresponding
> > GSource (which is pretty common when dealing with GPollFDs), given that you use
> > sources differently than in the timout/idle way.
> > 
> > but to actually make use of the GPollFD, i.e. to evaluate .revents, you need a
> > pointer to it, and that's what the user_data in (*check) and (*prepare) is for.
> 
> This is slightly bizarre, to me. 
> 
> Bite the bullet, create a structure, put your GPollFD 
> pointer into it, and pass it as the gsource and get it over
> with.

sure, i would have done that if there had been no user_data in the first place,
but since we do provide a user_data pointer with GSources, there's simply no
point in not passing that along in the appropriate callbacks.
the old way would have made me create a structure
struct {
 gpointer source_data;
 GPollFD* user_data;
 GDestroyNotifier user_data_destroy;
};
just to get access to this from (*check) and (*prepare), eventhough user_data
was designed to cover exactly this need. that appeared too ironic to me, to
not fix it.

> The reason why the user_data pointer is separate from the source
> is basically to allow the source to get the appropriate 
> GDestroyNotify behavior without duplicating code.

that is nice, but there is little sense in providing a user_data pointer
and then attempting to hide that from the user ;)
besides, the user_data being seperate from the source doesn't imply it
shouldn't be passed to (*check) or (*prepare).

> Nothing else in G* passes in _two_ gpointer of data to
> each function. What if you need three? or four?

well, everywhere in G*, we do pass along the user_data pointer if there
is one, often in additiona to special structure related pointers, such as
a GList* or GSList* in GFunc called from _foreach, or key_id and data in
GDataForeachFunc called from g_datalist_foreach.
so to do that for GSources as well is just pretty straight forward.

>  
> Regards,
>                                         Owen
> 
> 

---
ciaoTJ



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