procedure TBoundedBuffer.ResetState;
{ Closes handles and deallocates memory.
Note that this must unblock threads in such a manner that they quit cleanly }
var
SemCount: integer;
LocalHandle: THandle;
begin
if FBufInit then
begin
WaitForSingleObject(FCriticalMutex, DefaultWaitTime);
FBufInit := false;
FBufSize := 0;
FreeMem(FBuf);
LocalHandle := FEntriesFree;
FEntriesFree := 0;
repeat
ReleaseSemaphore(LocalHandle, 1, @SemCount);
until SemCount = 0;
CloseHandle(LocalHandle);
LocalHandle := FEntriesUsed;
FEntriesUsed := 0;
repeat
ReleaseSemaphore(LocalHandle, 1, @SemCount);
until SemCount = 0;
CloseHandle(LocalHandle);
CloseHandle(FCriticalMutex);
end;
end;