> There is no "global" variable named errno, it only exist in the TLS.  You
> could say that because there is only 1 TLS, that it's global, and it
> acts that way.  But it's not really the same as a normal global
> variable.  You can't access the variables in the same manner you access
> other global variables.

Is the following code legal:

void foo(void)
{
 static int *my_errno=NULL;
 if(my_errno==NULL) my_errno=errno;
 // code that uses 'my_errno' as if it were 'errno'
}

The answer is that if you're compiled single-threaded, it's perfectly legal.
If you're multi-threaded, it's not.

This might be a perfectly sensible optimization to condition on '_REENTRANT'
not being defined. In principle, the compiler might do such a thing
automatically if the overhead of TLS were higher than the overhead of the
test.

> In case of errno on a glibc system with NPTL there is no difference in the
> compiled code.  You always get the same function call.

Exactly. The precise same code can have a very different semantic meaning
depending upon whether it is used in a multi-threaded or a single-threaded
process. That's why you *must* specify appropriate compilation flags. The
code may need to change so that it can produce *different* code to get the
*same* semantic meaning.

> Let's assume for a moment that openssl is not "compiled for multi
> thread", whatever you mean with that exactly.  Even when the application
> is using threads, when openssl tries to use errno it will get the one for
> the current thread.

Really? Even if it's coded like my 'foo' above? It will magically always get
the right 'errno'? How?!

> > That these two different semantics are implemented by the same
> > code doesn't
> > change the fact that the semantics are different. In fact, it makes the
> > important point that the semantics of code can be changed by whether the
> > process is single-threaded or multi-threaded.

> I'm not at all saying that the semantics are the same.  All I'm saying
> is that in case of errno on a recent glibc there is no difference in the
> compiled code depending on wether your application or library is
> multi-threaded or not.

There is a huge difference. In the case of a single-threaded process, it
will get a process global 'errno' and optimizations such as my 'foo'
function above are perfectly legal. In the case of a multi-threaded process,
they're not.

> > On many Linux distributions, it is perfectly acceptable to do
> the following:
> >
> > #ifdef _REENTRANT
> > // inefficient thread-safe code
> > #else
> > // more efficient code that assumes 'errno' is process-global
> > #endif

> On many Linux distributions it's required that if such code is in a
> library that it's compiled using -D_REENTRANT for the packages
> they ship.  With other words, if the library can be compiled
> reentrant, that's what we want.

Right, and the OP is saying he doesn't have to compile with -D_REENTRANT (or
whatever else is specified on his platform as required for multi-threaded
code) and he can still use the library in a multi-threaded process.

I'm saying he can't do this even if he thinks the code will be the same
because the "same code" can mean something different. Different code may be
needed to get the same *effect*.

Compiling code without the compilation flags your platform documents as
required to get thread-safety guarantees and then using that compiled code
in a multi-threaded process is simply off the map. Anything can happen. Here
be dragons. This is so even in the case of Linux, where all the flags do (at
least, on most Linux platforms, AFAICT) is add a single define to the
compilation and a library to the linking.

And it's a bad idea even if you know it's safe on a particular platform. 9
times out of 10, code winds up running on platforms you never expected. If
these assumptions are no longer true on that platform, you may get code that
appears to work but has subtle bugs that cause it to do the wrong thing
under load. This is precisely the type of issue that can cause information
intended for one client to go to another. Not a good think in an
encryption/security context.

DS


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to