apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mladen Turk <mt...@apache.org>
Subject Re: svn commit: r434327 - in /apr/apr/trunk: CHANGES include/arch/win32/apr_arch_threadproc.h misc/win32/start.c threadproc/win32/threadpriv.c
Date Tue, 29 Aug 2006 12:24:24 GMT
Branko ─îibej wrote:
> 
> I know that boost_thread uses this method, and I've verified that it
> works on AMD64 and IA64; the tric is, I believe, that Boost inserts a
> single static handler into the static constructor and destructor
> segments, and lets that handler maintain its own list of hooks.
> 

Here is the entire code:


#if (_MSC_VER < 1310)
typedef void (__cdecl *_PVFV)(void);
#define INIRETSUCCESS
#define PVAPI void
#else
typedef int (__cdecl *_PVFV)(void);
#define INIRETSUCCESS 0
#define PVAPI int
#endif

typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
/* Symbols for connection to the runtime environment */
extern DWORD _tls_used;
extern _TLSCB __xl_a[], __xl_z[];

/* Global TLS hash table */
apr_hash_t *apr_tls_threadkeys = NULL;

typedef (apr_thredkey_destfn_t)(void *data);

static void threadkey_detach()
{
     apr_hash_index_t *hi = apr_hash_first(NULL, apr_tls_threadkeys);

     for (; hi != NULL; hi = apr_hash_next(hi)) {
         apr_thredkey_destfn_t *dest = NULL;
         LPDWORD key;
         void *data;
         apr_hash_this(hi, &key, NULL, (void **)&dest);
         data = TlsGetValue(*key);
         if (data != NULL || GetLastError() == ERROR_SUCCESS) {
             /* NULL data is a valid TLS value if explicitly set
              * by the TlsSetValue
              */
             (*dest)(data);
         }
     }
}

static PVAPI threadkey_prepare(void)
{
     DWORD volatile dw = _tls_used;

#if (_MSC_VER < 1310)
     _TLSCB* pfbegin = __xl_a;
     _TLSCB* pfend   = __xl_z;
     _TLSCB* pfdst   = pfbegin;

     while (pfbegin < pfend) {
         if (*pfbegin != 0) {
             *pfdst = *pfbegin;
             ++pfdst;
         }
         ++pfbegin;
     }
     *pfdst = 0;
#endif
     return INIRETSUCCESS;
}

static void NTAPI threadkey_callback(HINSTANCE hInstance, DWORD dwReason,
                                      PVOID pReserved)
{
     switch (dwReason) {
         case DLL_THREAD_DETACH:
             if (apr_tls_threadkeys)
                 threadkey_detach();
         break;
     }
}

#if (_MSC_VER >= 1310)
#pragma data_seg(push, old_seg)
#endif
/* Callback to run tls glue code first. */
#pragma data_seg(".CRT$XIU")
static _PVFV p_threadkey_prepare = threadkey_prepare;
#pragma data_seg()

/* Callback for tls notifications. */
#pragma data_seg(".CRT$XLB")
static _TLSCB p_threadkey_callback = threadkey_callback;
#pragma data_seg()

#if (_MSC_VER >= 1310)
#pragma data_seg(pop, old_seg)
#endif


Mime
View raw message