Просьба сразу не пинать ногами, в Free Pascal и Linux - новичок.
Есть dll под windows, написанная на FPC, она использует threadvar и чистит их автоматически при завершении треда с использованием Dll_Thread_Detach_Hook
Сама она потоками не управляет, так как это плагин (UDF для СУБД Firebird)
Есть задача перевести ее на Linux. Там, естественно никаких Dll_Thread_Detach_Hook нет, но есть TThreadManager.
Но видимо я неправильно себе представляю, как его прикрутить.
Код примерно такой (с большими сокращениями):
- Код: Выделить всё
uses
{$ifdef unix}cthreads,{$endif}
SysUtils, Classes, MemTableList, IBLog;
procedure IniDllProc;
{$IFDEF WINDOWS}
procedure LibraryProcThreadDetach(Reason: LongInt);
{$ELSE}
procedure LibraryReleaseThreadVars;
{$ENDIF}
var
{$IFDEF WINDOWS}
oldProcThreadDetach: TDLL_Entry_Hook = nil;
{$ELSE}
oldReleaseThreadVars: TReleaseThreadVarsHandler = nil;
{$ENDIF}
threadvar
VarList: TStringList;
TableList: TTableList;
ListList: TStringList;
implementation
procedure IniDllProc;
{$IFDEF UNIX}
var CurrentTM: TThreadManager;
{$ENDIF}
begin
{$IFDEF WINDOWS}
oldProcThreadDetach := Dll_Thread_Detach_Hook;
Dll_Thread_Detach_Hook := @LibraryProcThreadDetach;
{$ELSE}
GetThreadManager(CurrentTM);
oldReleaseThreadVars := CurrentTM.ReleaseThreadVars;
CurrentTM.ReleaseThreadVars := @LibraryReleaseThreadVars;
{$ENDIF}
end;
{$IFDEF WINDOWS}
procedure LibraryProcThreadDetach(Reason: LongInt);
begin
Log('DLL_THREAD_DETACH');
freeVarList;
freeTableList;
freeListList;
if Assigned(oldProcThreadDetach) then oldProcThreadDetach(Reason);
end;
{$ELSE}
procedure LibraryReleaseThreadVars;
begin
Log('ReleaseThreadVars');
freeVarList;
freeTableList;
freeListList;
if Assigned(oldReleaseThreadVars) then oldReleaseThreadVars;
end;
{$ENDIF}
При инициализации библиотеки вызывается код
- Код: Выделить всё
begin
IsMultiThread := True;
IniDllProc;
end.
Процедуры freeVarList, freeTableList, freeListList как раз чистят threadvar'ы.
Под виндой все работает нормально - в логе появляется 'DLL_THREAD_DETACH', память освобождается, под линуксом в LibraryReleaseThreadVars не заходит судя по всему никогда (в логе ничего нет, память не освобождается)
Подскажите, как заставить это работать или какие еще есть способы под линуксом отловить завершение треда (при условии, что не мы его создаем и завершаем) и почистить его threadvar'ы?