On Mon, Jan 28, 2008 at 02:22:09PM -0800, David Schwartz wrote:
>
> > errno is stored in Thread Local Storage (TLS). You can't link to the
> > global errno anymore.

>
> For a single-threaded process, there is no distinction between thread-local
> storage and a global variable. For a multi-threaded process, there is.


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.

> The same code can have a different semantic meaning depending upon whether
> the process is single-threaded or multi-threaded.
>
> > Using "extern int errno" will actually result in a linking error:
> > /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section
> > .tbss mismatches non-TLS reference

>
> My point was simply that there is a difference between single-threaded and
> multi-threaded compilation. In one case, 'errno' refers to a variable that
> is process global (since there is only one thread). In the other case, it
> does not.


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.

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.

> 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.

> 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.


Kurt

__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org