This commit is contained in:
Igor Pavlov
2021-07-22 23:00:14 +01:00
committed by Kornel
parent 4a960640a3
commit 585698650f
619 changed files with 34904 additions and 10859 deletions

View File

@@ -8,45 +8,63 @@
#include "../IStream.h"
/*
We don't use probably UNSAFE version:
reader thread:
We can use one from two code versions here: with Event or with Semaphore to unlock Writer thread
The difference for cases where Reading must be closed before Writing closing
1) Event Version: _canWrite_Event
We call _canWrite_Event.Set() without waiting _canRead_Event in CloseRead() function.
The writer thread can get (_readingWasClosed) status in one from two iterations.
It's ambiguity of processing flow. But probably it's SAFE to use, if Event functions provide memory barriers.
reader thread:
_canWrite_Event.Set();
_readingWasClosed = true
_readingWasClosed = true;
_canWrite_Event.Set();
writer thread:
writer thread:
_canWrite_Event.Wait()
if (_readingWasClosed)
Can second call of _canWrite_Event.Set() be executed without memory barrier, if event is already set?
2) Semaphore Version: _canWrite_Semaphore
writer thread always will detect closing of reading in latest iteration after all data processing iterations
*/
class CStreamBinder
{
NWindows::NSynchronization::CAutoResetEvent _canWrite_Event;
NWindows::NSynchronization::CManualResetEvent _canRead_Event;
NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event;
NWindows::NSynchronization::CAutoResetEvent _canRead_Event;
// NWindows::NSynchronization::CAutoResetEvent _canWrite_Event;
NWindows::NSynchronization::CSemaphore _canWrite_Semaphore;
// bool _readingWasClosed;
bool _readingWasClosed2;
// bool _readingWasClosed; // set it in reader thread and check it in write thread
bool _readingWasClosed2; // use it in writer thread
// bool WritingWasCut;
bool _waitWrite;
bool _waitWrite; // use it in reader thread
UInt32 _bufSize;
const void *_buf;
public:
UInt64 ProcessedSize;
UInt64 ProcessedSize; // the size that was read by reader thread
WRes CreateEvents();
void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
void CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream);
void ReInit();
HRESULT Create_ReInit();
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
void CloseRead()
void CloseRead_CallOnce()
{
_readingWasClosed_Event.Set();
// _readingWasClosed = true;
// _canWrite_Event.Set();
// call it only once: for example, in destructor
/*
_readingWasClosed = true;
_canWrite_Event.Set();
*/
/*
We must relase Semaphore only once !!!
we must release at least 2 items of Semaphore:
one item to unlock partial Write(), if Read() have read some items
then additional item to stop writing (_bufSize will be 0)
*/
_canWrite_Semaphore.Release(2);
}
void CloseWrite()