title: Access NULL data on TLS object on Windows
body: <p>I encountered a weird thing out of my understanding about TLS object access on windows. I set a global object into TLS, and access its data "test_sym" from somewhere say test.cpp like the code below. It works on Mac, but on windows test_sym returns NULL. But if I explicitly defined test_sym in test.cpp (static Persistent test_sym), then it works on windows... </p>
  
  <p>in var.h</p>
  
  <pre><code>#define VAR(x) (globals_get()-&gt;x)
  
  struct globals {
  v8::Persistent&lt;v8::String&gt; test_sym;
  ...
  };
  
  globals* globals_get();
  </code></pre>
  
  <p>in var.cpp</p>
  
  <pre><code>#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(&amp;loop_key, NULL);
  #endif
  }
  
  globals* globals_get() {
    uv_once(&amp;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&lt;globals*&gt;(data);
  }
  </code></pre>
  
  <p>Two ways to define test_sym in test.cpp, a does not work, but b works well.</p>
  
  <p>Way a:</p>
  
  <pre><code> #include "vars.h"
   #define test_sym VAR(test_sym)
   ...
   void test()
   {
       HandleScope scope;
       object_-&gt;Set(test_sym, Integer::New(stream_-&gt;write_queue_size));// test_sym is NULL on windows!!!
   }
  </code></pre>
  
  <p>Way b:</p>
  
  <pre><code>static Persistent&lt;String&gt; test_sym;
  ...
  void test()
  {
      HandleScope scope;
      object_-&gt;Set(test_sym, Integer::New(stream_-&gt;write_queue_size));// test_sym is OK.
  }
  </code></pre>