summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Common/StreamBinder.h')
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamBinder.h60
1 files changed, 39 insertions, 21 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
index 12088a94586..c0a70793c4b 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.h
@@ -1,52 +1,70 @@
// StreamBinder.h
-#ifndef __STREAM_BINDER_H
-#define __STREAM_BINDER_H
+#ifndef ZIP7_INC_STREAM_BINDER_H
+#define ZIP7_INC_STREAM_BINDER_H
#include "../../Windows/Synchronization.h"
#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()