Добрый день. Есть необходимость поработать с thread local storage в DLL, которая реализует callback-функции для стороннего приложения. Взял пример из MSDN:
// The DLL code#include <windows.h>
static DWORD dwTlsIndex; // address of shared memory
// DllMain() is the entry-point function for this DLL.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD fdwReason, // reason called
LPVOID lpvReserved) // reserved
{
LPVOID lpvData;
BOOL fIgnore;
switch (fdwReason)
{
// The DLL is loading due to process
// initialization or a call to LoadLibrary. case DLL_PROCESS_ATTACH:
// Allocate a TLS index.if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return FALSE;
// No break: Initialize the index for first thread.
// The attached process creates a new thread. case DLL_THREAD_ATTACH:
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, 256);
if (lpvData != NULL)
fIgnore = TlsSetValue(dwTlsIndex, lpvData);
break;
// И так далее...
Так вот, при первом вызове из потока ф-ция TlsGetValue(dwTlsIndex) всегда возвращает NULL. Если снова вызвать TlsSetValue (уже в теле потока), то все начинает работать нормально. Другими словами — куда пропал указатель lpvData, изначально сохраненный в функции DLLMain? Или так и должно быть? Или я где-то туплю?
Заранее спасибо за ответы.
V>Так вот, при первом вызове из потока ф-ция TlsGetValue(dwTlsIndex) всегда возвращает NULL. Если снова вызвать TlsSetValue (уже в теле потока), то все начинает работать нормально. Другими словами — куда пропал указатель lpvData, изначально сохраненный в функции DLLMain? Или так и должно быть? Или я где-то туплю? V>Заранее спасибо за ответы.
1) поток, который выделен в тексте, является ли тем потоком, который загрузил dll?
если ответ на вопрос 1) — "нет" — то другой вопрос: 2) поток, который выделен в тексте, запущен ли он после загрузки dll?
если ответ на вопросы 1) и 2) — нет — то так и должно быть, ибо ни DLL_PROCESS_ATTACH ни DLL_THREAD_ATTACH не приходят для других потоков приложения, которые стартовали до загрузки длл.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
O>1) поток, который выделен в тексте, является ли тем потоком, который загрузил dll? O>если ответ на вопрос 1) — "нет" — то другой вопрос: 2) поток, который выделен в тексте, запущен ли он после загрузки dll? O>если ответ на вопросы 1) и 2) — нет — то так и должно быть, ибо ни DLL_PROCESS_ATTACH ни DLL_THREAD_ATTACH не приходят для других потоков приложения, которые стартовали до загрузки длл.
1) "Да" — если судить по ID потока. Хотя допускаю, что ID может быть использован повторно другим потоком. Впрочем, я смотрел — THREAD_DETACH для потока не приходит (по крайней мере, между вызовами TlsSetValue и TlsGetValue). Получается, что изначальный поток "жестко" убивают, а его ID "быстренько" начинает юзать какой-то новый поток? Это уж совсем как-то криво...
Хотя приложение чужое, поэтому тонкости его работы, увы, сообщить не могу...
V>1) "Да" — если судить по ID потока. Хотя допускаю, что ID может быть использован повторно другим потоком. Впрочем, я смотрел — THREAD_DETACH для потока не приходит (по крайней мере, между вызовами TlsSetValue и TlsGetValue). Получается, что изначальный поток "жестко" убивают, а его ID "быстренько" начинает юзать какой-то новый поток? Это уж совсем как-то криво... V>Хотя приложение чужое, поэтому тонкости его работы, увы, сообщить не могу...
Дебажить надо, таких проблем с TLS сроду не видел.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, ononim, Вы писали:
V>>1) "Да" — если судить по ID потока. Хотя допускаю, что ID может быть использован повторно другим потоком. Впрочем, я смотрел — THREAD_DETACH для потока не приходит (по крайней мере, между вызовами TlsSetValue и TlsGetValue). Получается, что изначальный поток "жестко" убивают, а его ID "быстренько" начинает юзать какой-то новый поток? Это уж совсем как-то криво... V>>Хотя приложение чужое, поэтому тонкости его работы, увы, сообщить не могу... O>Дебажить надо, таких проблем с TLS сроду не видел.
Разобрался с помощью дебага — допустил типичную ламерскую ошибку . Статическую переменную TlsIndex я необдуманно перенес (и на фиг забыл про это) из dllmain.cpp в stdafx.h — что вызвало ее размножение по разным cpp-файлам...
Спасибо за помощь и пардон за тупость — ушел перечитывать теорию )