Re: Thread specific data for GLib
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list redhat com
- Subject: Re: Thread specific data for GLib
- Date: 07 Dec 1998 18:28:48 -0500
Sebastian Wilhelmi <wilhelmi@ira.uka.de> writes:
> Hi, Owen
>
> > While testing out the thread-safety patches to GLib,
> > I ran into one problem that I don't see how to
> > solve without adding thread-specific data to our
> > set of primitives -
>
> Ah, I havn't seen that yet, but I already wrote "MT safe" into the header,
> makes me wonder, how reliable my other "MT safe" remarks are ;-)
Well, once we figure out the basics, I'll make a careful
read-through to try and find holes.
This particular problem though was pretty simple to find -
since it was static data that was neither per-thread
or locked.
> [ snip ]
> > It would then be easy to provide,
> > on top of that, a more "G-ish" interface that provided
> > the optional ability to associate data with character
> > keys instead of numeric ID's. (I.e., something along
> > the lines of GDataSet / GDataList)
>
> Thats not good, that is asking for trouble (is this case it is asking for
> name space collisions).
And functions are asking for trouble because their is only
a single namespace...
Using prefixes in ones key should keep that from being a
problem.
> I have however added a (I think) quite G-ish
> addition, that again can be statically initialized, it of course needs a
> mutex call there, but that is an acaptable cost, because you gain a quite
> nice interface. You can alos set a constuctor, that is used every time the
> private data is read and would be NULL. and you can destroy a key and all
> data related to it (thats not possible under either solaris or posix).
> You'll soon find a patch in
>
> ftp.gtk.org/incoming/glib-wilhelmi-981207.patch*
>
> Bye,
> Sebastian
>
> PS.: There still are some rough edges, but in general I am quite content
> with my solution. ;-) (so at least someone is)
For other people's reference the API is below. IMO, it is
neither terribly G'ish, nor like any other thread-private
data I've seen. That isn't to say it is bad, just a little
unusual. (The use of integer indices for thread specific
data seems to be pretty universal)
[ The no-threads part of g_private_set needs fixing
in any case ... lvalue casts aren't standard C ]
In general, I'd like to stick to something a lot closer
to the metal. All this StaticPrivate stuff may, IMO,
is really over-complicated, and may not match the
needs of the application.
The question, though, is how to provide a convenient
interface to getting a unique thread index to use
for your a bit of static data, without requiring
locking on each fetch of the static data.
Netscape generally uses constructors to set up the
the TSD indices; using pthreads you can use
pthread_once(). I'm not quite sure what the right
approach is for GLib, but at least for gmessage.c,
it's easy, since we are already locking a mutex,
we can just use that to guard the initialization.
Regards,
Owen
=======
#define g_private_new(destructor) \
G_USE_PRIVATE_FUNC(private_new,NULL,(destructor))
#define g_private_get(private) \
G_USE_PRIVATE_FUNC(private_get,((gpointer)private),(private))
#define g_private_set(private,value) \
G_USE_PRIVATE_FUNC(private_set,(void)(((gpointer)private)=(value)), \
(private,value))
struct _GStaticPrivate
{
/* constructor is called by g_private_get */
GNewFunc constructor;
/* destructor is called, when the thread ends */
GDestroyNotify destructor;
/* if size is non-zero, constructor is taken to be g_malloc0(size)
and destructor is g_free */
guint size;
/* do not use the following element */
guint id;
};
#define G_STATIC_PRIVATE_INIT_FOR_SIZE(size) \
{ NULL, NULL, size, 0 }
#define G_STATIC_PRIVATE_INIT_FOR_TYPE(constructor,destructor) \
{ constructor, destructor, 0, 0 }
GStaticPrivate* g_static_private_new_for_size(guint size);
GStaticPrivate* g_static_private_new_for_type(GNewFunc constructor,
GDestroyNotify destructor);
gpointer g_static_private_get(GStaticPrivate* private );
void g_static_private_set(GStaticPrivate* private, gpointer value );
void g_static_private_free(GStaticPrivate* private);
=======
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]