You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Paul Sutton <pa...@eu.c2.net> on 1997/12/01 12:45:22 UTC

PR#1168: APACHE_TLS does not work in Modules

RP#1168 is right. If you LoadModule a DLL under windows, that
DLL code cannot include any APACHE_TLS variables. This is a Win32 and/or
MSVC++ bug. See MS Knowledge Base article 118816 (appended below to save
time). 

Basically APACHE_TLS (or __declspec(thread)) creates some thread-local
storage but *only enough for* statically linked DLLs. Any DLLs loaded
dynamically won't have a space in the thread-local storage area.

This means basically modules can't use APACHE_TLS, except for the dozen or
so that link directly into ApacheCore. We should probably remove
APACHE_TLS from the API that third-party modules see. DLL modules have to
use Tls*() functions instead.

Paul

----

PRB: LoadLibrary() Fails with _declspec(thread)
Article ID: Q118816 
Creation Date: 31-JUL-1994
Revision Date: 25-SEP-1995 
The information in this article applies to: 

Microsoft Win32 Application Programming Interface (API) included with: 

    - Microsoft Windows NT versions 3.1, 3.5, and 3.51
    - Microsoft Windows 95 version 4.0
    - Microsoft Win32s versions 1.1, 1.15, 1.2, and 1.25a

SYMPTOMS 

Your dynamic-link library (DLL) uses __declspec(thread) to allocate thread
local storage (TLS). There are no problems running an application that is
statically linked with the DLL's import library. However, when an
application uses LoadLibrary() to load the DLL instead of using the import
library, LoadLibrary() fails on Win32s with "error 87: invalid parameter". 
LoadLibrary() succeeds under Windows NT in this situation; however, the
application cannot successfully call functions in the DLL. 

CAUSE 

This is a limitation of LoadLibrary() and __declspec(). The global
variable space for a thread is allocated at run time. The size is based on
a calculation of the requirements of the application plus the requirements
of all of the DLLs that are statically linked. When you use LoadLibrary(),
there is no way to extend this space to allow for the thread local
variables declared with __declspec(thread). This can cause a protection
fault either when the DLL is dynamically loaded or code references the
data. 

RESOLUTION 

DLLs that use __declspec(thread) should not be loaded with LoadLibrary(). 

Use the TLS APIs, such as TlsAlloc(), in your DLL to allocate TLS if the
DLL might be loaded with LoadLibrary(). If you continue to use
_declspec(), warn users of the DLL that they should not load the DLL with
LoadLibrary().