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;