I use dxsock and I always get an error 6 Invalid Handle from windows when I
terminate my server.
This is triggered inside the function TThread.WaitFor.
I'll explain what happens.
In the main thread the function WaitFor Is Called
This will copy the handle to a variable H.
It will use this handle to call the function MsgWaitForMultipleObjects.
If the threads FreeOnTerminate is True it will free this handle.
Therefor making this handle Invalid.
Therefor resulting in the error triggered by Win32Check;
This is extremely irritating, we have made a workaround, it requires a
duplicatehandle. We have a workaround now, but I would like to see this
modified in newer versions of Delphi. I don't like me making modifications
in the source.
In order to get it working, compile this file and put the new classes.DCU in
Lib.
Kind regards
Alexander
Snip from D6 source.
var
H: THandle;
WaitResult: Cardinal;
Msg: TMsg;
begin
H := FHandle;
if GetCurrentThreadID = MainThreadID then
begin
WaitResult := 0;
repeat
{ This prevents a potential deadlock if the background thread
does a SendMessage to the foreground thread }
if WaitResult = WAIT_OBJECT_0 + 1 then
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
Sleep(0);
CheckSynchronize;
WaitResult := MsgWaitForMultipleObjects(1, H, False, 0,
QS_SENDMESSAGE);
Win32Check(WaitResult <> WAIT_FAILED);
until WaitResult = WAIT_OBJECT_0;
end else WaitForSingleObject(H, INFINITE);
CheckThreadError(GetExitCodeThread(H, Result));
end;
WorkAround
function TThread.WaitFor: LongWord;
{$IFDEF MSWINDOWS}
var
PH : THandle;
H: THandle;
WaitResult: Cardinal;
Msg: TMsg;
begin
PH := getCurrentProcess;
DuplicateHandle(PH, FHandle, PH, @H, 0, false, DUPLICATE_SAME_ACCESS);
if GetCurrentThreadID = MainThreadID then
begin
WaitResult := 0;
repeat
{ This prevents a potential deadlock if the background thread
does a SendMessage to the foreground thread }
if WaitResult = WAIT_OBJECT_0 + 1 then
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
Sleep(0);
CheckSynchronize;
WaitResult := MsgWaitForMultipleObjects(1, H, False, 0,
QS_SENDMESSAGE);
Win32Check(WaitResult <> WAIT_FAILED);
until WaitResult = WAIT_OBJECT_0;
end else WaitForSingleObject(H, INFINITE);
CheckThreadError(GetExitCodeThread(H, Result));
CloseHandle(H);
end;
Not to piss anyone off,
but IMHO a guy implementing the new TThread.WaitFor, should *NOT* make such
an obvious mistake. This is a very basic thread shit.
Kind regards
Alexander
>I use dxsock
...
>In the main thread the function WaitFor Is Called
>This will copy the handle to a variable H.
>It will use this handle to call the function MsgWaitForMultipleObjects.
>If the threads FreeOnTerminate is True it will free this handle.
>Therefor making this handle Invalid.
>Therefor resulting in the error triggered by Win32Check;
Please tell the dxsock folks to fix their defect.
They cannot have FreeOnTerminate = true *and* call WaitFor.
This is *NOT* a bug and Stefan is right.
Kind regards
Alexander