我对 Windows 上的 TLS 对象访问的理解遇到了一件奇怪的事情。我将一个全局对象设置为 TLS,并从某个地方访问它的数据“test_sym”,比如 test.cpp,如下面的代码。它适用于 Mac,但在 Windows 上 test_sym 返回 NULL。但是如果我在 test.cpp 中明确定义了 test_sym(静态 Persistent test_sym),那么它可以在 Windows 上运行......
在 var.h
#define VAR(x) (globals_get()->x)
struct globals {
v8::Persistent<v8::String> test_sym;
...
};
globals* globals_get();
在 var.cpp 中
#if defined(_WIN32)
static unsigned long loop_key;
#else
static pthread_key_t loop_key;
#endif
static uv_once_t tls_once_guard = UV_ONCE_INIT;
static void init_tls() {
#if defined(_WIN32)
loop_key = TlsAlloc();
#else
pthread_key_create(&loop_key, NULL);
#endif
}
globals* globals_get() {
uv_once(&tls_once_guard, init_tls);
#if defined(_WIN32)
void* data = TlsGetValue(loop_key);
#else
void* data = pthread_getspecific(loop_key);
#endif
if (data == NULL) {
data = new globals();
#if defined(_WIN32)
TlsSetValue(loop_key, data);
#else
pthread_setspecific(loop_key, data);
#endif
}
return static_cast<globals*>(data);
}
在 test.cpp 中定义 test_sym 的两种方式,a 不行,但 b 可以。
方式一:
#include "vars.h"
#define test_sym VAR(test_sym)
...
void test()
{
HandleScope scope;
object_->Set(test_sym, Integer::New(stream_->write_queue_size));// test_sym is NULL on windows!!!
}
方式b:
static Persistent<String> test_sym;
...
void test()
{
HandleScope scope;
object_->Set(test_sym, Integer::New(stream_->write_queue_size));// test_sym is OK.
}