destructor TPipeClient.Destroy;
begin
// Disconnect if connected
Disconnect(false);
// Free resources
FinalizeSecurity(FSA);
CloseHandle(FKillEv);
FWriteQueue.Free;
DeAllocateHWnd(FHwnd);
// Perform inherited
inherited Destroy;
end;
procedure TPipeClient.Disconnect(
const CanWait:Boolean);
begin
if not Assigned(self)
then
Exit;
// Exit if not connected
if not(FConnected)
then exit;
// Signal the kill event
SetEvent(FKillEv);
// Terminate and wait for the worker thread to finish
if Assigned(FWorker)
then FWorker.Terminate;
// *** Added by Russell on 01.19.2004 ***
// Only wait if we are not in a destroying state
if CanWait
and not (csDestroying
in ComponentState)
then
FWorker.WaitFor;
// Set new state
FConnected:=False;
end;
procedure TPipeClientThread.Execute;
var dwEvents: Integer;
bOK: Boolean;
begin
// Loop while not terminated
while not(Terminated)
do
begin
// Make sure we always have an outstanding read and write queued up
bOK:=(QueuedRead
and QueuedWrite);
if bOK
then
begin
// If we are in a pending write then we need will not wait for the
// DataEvent, because we are already waiting for a write to finish
dwEvents:=4;
if FPendingWrite
then Dec(dwEvents);
// Handle the event that was signalled (or failure)
case WaitForMultipleObjects(dwEvents, @FEvents, False, INFINITE)
of
// Killed by pipe server
WAIT_OBJECT_0 : Terminate;
// Read completed
WAIT_OBJECT_0+1 : bOK:=CompleteRead;
// Write completed
WAIT_OBJECT_0+2 : bOK:=CompleteWrite;
// Data waiting to be sent
WAIT_OBJECT_0+3 : ;
// Data available to write
else
// General failure
FErrorCode:=GetLastError;
bOK:=False;
end;
end;
// Check status
if not(bOK)
then
begin
// Call OnError in the main thread if this is not a disconnect. Disconnects
// have their own event, and are not to be considered an error
if (FErrorCode <> ERROR_PIPE_NOT_CONNECTED)
then PostMessage(FNotify, WM_PIPEERROR_W, FPipe, FErrorCode);
// Terminate
Terminate;
end;
end;
// Make sure the handle is still valid
if (FErrorCode <> ERROR_INVALID_HANDLE)
then
begin
DisconnectNamedPipe(FPipe);
CloseHandle(FPipe);
end;
// Close all open handles that we own
CloseHandle(FOlapRead.hEvent);
CloseHandle(FOlapWrite.hEvent);
end;