[wx-dev] wxThread, thread local storage and wxLog

Armel Asselin asselin.armel at wanadoo.fr
Thu Aug 10 09:44:11 PDT 2006


> AA> ok, ok, so maybe this issue could be solve outside from the framework
> AA> itself, if i make by myself a wxLog object which uses a wxTLS slot to 
> store
> AA> a job id (NOT a thread id), and then this wxLog is able to distribute 
> to the
> AA> right log window, it could be ok.
>
> We're still talking past each other. Why do you need wxTLS slot for this?
> TLS can be replaced (more or less) by a map using thread ids as keys, you
> need either one or the other, not both.
for sure i don't need both, but using a map with thread id to obtain the job 
id will create contention which is nicely avoided with TLS.

> AA> > AA> and there is a wxThread object per thread already (only main 
> thread
> AA> > AA> does not have),
> AA> >
> AA> > Well, and how do you think this wxThread object is associated with 
> each
> AA> > thread? Using TLS, of course.
> AA> aaarrrghhh, you tell not use more tls entries because the developper 
> using
> AA> wx could exhaust the system tls, so I think of a solution to reuse in 
> some
> AA> manner the wxThread object
>
> But yes, of course I want to reuse the same TLS slot. I thought it was
> clear but let me make it even more clear: instead of using the TLS slot we
> currently use for wxThread object it would be better to use it for
> wxThreadData object which would, among other things, contain wxThread
> pointer. This is preferable to putting the per-thread data in wxThread
> object itself for many reasons (I wouldn't be surprised by now if you told
> me that you don't see them but please try).
>
> AA> another reason from the wxTLS implementation point of view, if I could 
> avoid
> AA> having per-platform sources by just using a single pointer in a 
> wxThread
> AA> object, it would make me really happy.
>
> This wouldn't make the library users happy however. A little extra effort
> (and it's a little one because the code is already there, it just needs to
> be refactored) to make a separate wxTLS class is justifiable here IMO.
>
> AA> from a user point of view, having wxTLS independent of wxThread would
> AA> allow one without the other, potentially useful when using a log 
> inside
> AA> a component launched from an application which is not wx aware (is
> AA> there already something which creates a dummy wxThread object on the
> AA> fly for threads which do not have one?).
>
> No.
>
> AA> > AA> wxLogNull is used internally by wx... it means that simply 
> calling wx
> AA> > AA> stuff, can give weird results in multi-threaded apps.
> AA> >
> AA> > This is an argument for wxLogNull to use 
> SetActiveLogTargetPerThread()
> AA> > (and not the global SetActiveTarget()), yes.
> AA> wxLogNull does not use SetActiveTarget at all currently. but if it was
> AA> derived from wxLog and if it installed itself with
> AA> SetActiveLogTargetPerThread, ok. note, that this issue could as well 
> be
> AA> solved with wxTLS entry containing an equivalent for the ms_doLog 
> boolean.
>
> Indeed.
ok for all of that, so let's summarize:
for TLS stuff?
- we should do a class named wxTheadLocalStorage or (wxTLS?)
- we must choose an allocation strategy: either we consider that using 
system TLS is safe on all platforms (old Windows had only 64 TLS entries per 
process, newer have 1088, linux and bsd seem to have usually 256), these 
entries are for all the libs loaded at the same time in the process, or we 
consider that it is risked and this case we allocate a single system TLS 
entry, and simply store wxTLS entries in an array inside a per-thread 
singleton wxTLS object. Personnaly I find it risked to presume that such or 
such system TLS will always be large enough, there are plenty of variables 
which are still marked as 'not MT-safe' in wx code (some of htem should 
probably get a wxTLSSLot).
- whatever the chosen storage, we can make a wxTLSSlot class which could 
allocate/free the TLS entry in constructor/destructor at module 
loading/unloading time (ie. process or dyn lib), and have a member set/get + 
a deletion function if wanted. a simple template wxTLSSingleton<T> could 
encapsulate that for the user.

for wxLog stuff:
- a (private or protected) object: wxLog::PerThreadData should be stored 
with wxTLSSlot. It would store all the data which may create problems if 
shared among threads, currently the ActiveTarget creates problems.
- SetActiveLogTargetPerThread( ) should use a wxTLSSlot. Used by wxLogNull 
(avoiding wxLog::ms_doLog global).

Armel





More information about the wx-dev mailing list