[Haskell] thread-local variables (was: Re: Implicit Parameters)
Frederik Eaton
frederik at a5.repetae.net
Mon Jul 31 12:35:45 EDT 2006
On Mon, Jul 31, 2006 at 03:09:59PM +0300, Einar Karttunen wrote:
> On 31.07 03:18, Frederik Eaton wrote:
> > I don't think it's necessarily such a big deal. Presumably the library
> > with the worker threads will have to be invoked somewhere. One should
> > just make sure that it is invoked in the appropriate environment, for
> > instance with the database connection already properly initialized.
> >
> > (*) One might even want to change the environment a little within each
> > thread, for instance so that errors get logged to a thread-specific
> > log file.
>
> So we have the following:
> 1) the library is initialized and spawns worker thread Tw
> 2) application initializes the database connection and it
> is associated with the current thread Tc and all the children
> it will have (unless changed)
> 3) the application calls the library in Tc passing an IO action
> to it. The IO action refers to the TLS thinking it is in
> Tc where it is valid.
> 4) the library runs the callback code in Tw where the TLS state is
> invalid. This is even worse than a global variable in this case.
If you have threads, and you have something which needs to be
different among different threads, then it is hard for me to see how
thread-local variables could be worse than global variables in any
case at all.
> Of course one can argue that the application should first initialize
> the database handle. But if the app uses worker threads (spawned
> before library initialization) then things will break if a library
> uses TLS and callbacks and they end up running in threads created
> before the library initialization.
OK, sure. In certain situations you have to keep track of whether a
function to which you pass an action might be sending it off to be run
in a different thread. We've been over this. Perhaps users should be
warned in the documentation - and in the documentation for exceptions
as well. I really don't see that as a problem that would sneak up on
people, since if you're passing an action to a function, rather than
executing it yourself, then in most cases it should be clear to
programmers that the action will run in a different context if not a
different thread altogether. And if you want to force the context to
be the same, you wrap the action in something restoring that context,
just like you would have to do with your state transformer monad
stack.
Another way to write buggy code is to have it so bloated with extra
syntax - e.g. with monad conversions, or extra function parameters, as
you propose - that it becomes impossible to read and understand.
Frederik
--
http://ofb.net/~frederik/
More information about the Haskell
mailing list