{"action":"closed","issue":{"url":"https://api.github.com/repos/jemalloc/jemalloc/issues/318","repository_url":"https://api.github.com/repos/jemalloc/jemalloc","labels_url":"https://api.github.com/repos/jemalloc/jemalloc/issues/318/labels{/name}","comments_url":"https://api.github.com/repos/jemalloc/jemalloc/issues/318/comments","events_url":"https://api.github.com/repos/jemalloc/jemalloc/issues/318/events","html_url":"https://github.com/jemalloc/jemalloc/issues/318","id":130146703,"number":318,"title":"jemalloc on Windows leaks TSD's","user":{"login":"rustyx","id":1296899,"avatar_url":"https://avatars.githubusercontent.com/u/1296899?v=3","gravatar_id":"","url":"https://api.github.com/users/rustyx","html_url":"https://github.com/rustyx","followers_url":"https://api.github.com/users/rustyx/followers","following_url":"https://api.github.com/users/rustyx/following{/other_user}","gists_url":"https://api.github.com/users/rustyx/gists{/gist_id}","starred_url":"https://api.github.com/users/rustyx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rustyx/subscriptions","organizations_url":"https://api.github.com/users/rustyx/orgs","repos_url":"https://api.github.com/users/rustyx/repos","events_url":"https://api.github.com/users/rustyx/events{/privacy}","received_events_url":"https://api.github.com/users/rustyx/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/jemalloc/jemalloc/labels/portability","name":"portability","color":"bfe5bf"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-01-31T16:22:14Z","updated_at":"2016-02-20T18:57:13Z","closed_at":"2016-02-20T18:57:13Z","body":"When built with MSVC 2015 on Windows, jemalloc is leaking TSD's, no matter if I link it statically or as a DLL.\r\n\r\nFurther analysis shows that the MSC-specific `_tls_callback` is never invoked in Release mode (however is working fine in Debug mode):\r\n\r\n```\r\nstatic BOOL WINAPI\r\n_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r\n{\r\n\r\n\tswitch (fdwReason) {\r\n#ifdef JEMALLOC_LAZY_LOCK\r\n\tcase DLL_THREAD_ATTACH:\r\n\t\tisthreaded = true;\r\n\t\tbreak;\r\n#endif\r\n\tcase DLL_THREAD_DETACH:\r\n\t\t_malloc_thread_cleanup();\r\n\t\tbreak;\r\n\tdefault:\r\n\t\tbreak;\r\n\t}\r\n\treturn (true);\r\n}\r\n#ifdef _MSC_VER\r\n#  ifdef _M_IX86\r\n#    pragma comment(linker, \"/INCLUDE:__tls_used\")\r\n#  else\r\n#    pragma comment(linker, \"/INCLUDE:_tls_used\")\r\n#  endif\r\n#  pragma section(\".CRT$XLY\",long,read)\r\n#endif\r\nJEMALLOC_SECTION(\".CRT$XLY\") JEMALLOC_ATTR(used)\r\nstatic BOOL\t(WINAPI *const tls_callback)(HINSTANCE hinstDLL,\r\n    DWORD fdwReason, LPVOID lpvReserved) = _tls_callback;\r\n#endif\r\n```\r\n\r\nMy guess is that the `.CRT$XLY` hack isn't working in MSVC 2015.\r\n\r\nThe only way I could work around this problem was to invoke it manually:\r\n\r\n```\r\n#include <jemalloc/jemalloc.h>\r\n#include <jemalloc/internal/jemalloc_internal_defs.h>\r\nextern \"C\" {\r\n\tvoid _malloc_thread_cleanup(void);\r\n\textern bool je_isthreaded;\r\n}\r\nstatic thread_local struct JeMallocThreadHelper {\r\n#ifdef JEMALLOC_LAZY_LOCK\r\n\tJeMallocThreadHelper() {\r\n\t\tje_isthreaded = true;\r\n\t}\r\n#endif\r\n\t~JeMallocThreadHelper() {\r\n\t\t_malloc_thread_cleanup();\r\n\t}\r\n} tls_jemallocThreadHelper;\r\n```\r\n\r\nNote this works only for C++ threads, but was sufficient for me.\r\n\r\nObviously, this is ugly and a better solution is needed.\r\n"}}