summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp95
1 files changed, 45 insertions, 50 deletions
diff --git a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
index 435440c6649..38334af9638 100644
--- a/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
+++ b/3rdparty/lzma/CPP/7zip/Common/StreamBinder.cpp
@@ -6,50 +6,48 @@
#include "StreamBinder.h"
-class CBinderInStream:
- public ISequentialInStream,
- public CMyUnknownImp
-{
+Z7_CLASS_IMP_COM_1(
+ CBinderInStream
+ , ISequentialInStream
+)
CStreamBinder *_binder;
public:
- MY_UNKNOWN_IMP1(ISequentialInStream)
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
- ~CBinderInStream() { _binder->CloseRead(); }
+ ~CBinderInStream() { _binder->CloseRead_CallOnce(); }
CBinderInStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
{ return _binder->Read(data, size, processedSize); }
-class CBinderOutStream:
- public ISequentialOutStream,
- public CMyUnknownImp
-{
+
+Z7_CLASS_IMP_COM_1(
+ CBinderOutStream
+ , ISequentialOutStream
+)
CStreamBinder *_binder;
public:
- MY_UNKNOWN_IMP1(ISequentialOutStream)
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
~CBinderOutStream() { _binder->CloseWrite(); }
CBinderOutStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+Z7_COM7F_IMF(CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
{ return _binder->Write(data, size, processedSize); }
-
-WRes CStreamBinder::CreateEvents()
+static HRESULT Event_Create_or_Reset(NWindows::NSynchronization::CAutoResetEvent &event)
{
- RINOK(_canWrite_Event.Create());
- RINOK(_canRead_Event.Create());
- return _readingWasClosed_Event.Create();
+ const WRes wres = event.CreateIfNotCreated_Reset();
+ return HRESULT_FROM_WIN32(wres);
}
-void CStreamBinder::ReInit()
+HRESULT CStreamBinder::Create_ReInit()
{
- _canWrite_Event.Reset();
- _canRead_Event.Reset();
- _readingWasClosed_Event.Reset();
+ RINOK(Event_Create_or_Reset(_canRead_Event))
+ // RINOK(Event_Create_or_Reset(_canWrite_Event))
+
+ // _canWrite_Semaphore.Close();
+ // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce()
+ _canWrite_Semaphore.OptCreateInit(0, 3);
// _readingWasClosed = false;
_readingWasClosed2 = false;
@@ -59,27 +57,14 @@ void CStreamBinder::ReInit()
_buf = NULL;
ProcessedSize = 0;
// WritingWasCut = false;
+ return S_OK;
}
-void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
+void CStreamBinder::CreateStreams2(CMyComPtr<ISequentialInStream> &inStream, CMyComPtr<ISequentialOutStream> &outStream)
{
- // _readingWasClosed = false;
- _readingWasClosed2 = false;
-
- _waitWrite = true;
- _bufSize = 0;
- _buf = NULL;
- ProcessedSize = 0;
- // WritingWasCut = false;
-
- CBinderInStream *inStreamSpec = new CBinderInStream(this);
- CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- *inStream = inStreamLoc.Detach();
-
- CBinderOutStream *outStreamSpec = new CBinderOutStream(this);
- CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
- *outStream = outStreamLoc.Detach();
+ inStream = new CBinderInStream(this);
+ outStream = new CBinderOutStream(this);
}
// (_canRead_Event && _bufSize == 0) means that stream is finished.
@@ -92,7 +77,9 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (_waitWrite)
{
- RINOK(_canRead_Event.Lock());
+ WRes wres = _canRead_Event.Lock();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
_waitWrite = false;
}
if (size > _bufSize)
@@ -105,17 +92,25 @@ HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
if (processedSize)
*processedSize = size;
_bufSize -= size;
+
+ /*
+ if (_bufSize == 0), then we have read whole buffer
+ we have two ways here:
+ - if we check (_bufSize == 0) here, we unlock Write only after full data Reading - it reduces the number of syncs
+ - if we don't check (_bufSize == 0) here, we unlock Write after partial data Reading
+ */
if (_bufSize == 0)
{
_waitWrite = true;
- _canRead_Event.Reset();
- _canWrite_Event.Set();
+ // _canWrite_Event.Set();
+ _canWrite_Semaphore.Release();
}
}
}
return S_OK;
}
+
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
@@ -135,20 +130,20 @@ HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSiz
_readingWasClosed2 = true;
*/
- HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
- DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
- if (waitResult >= WAIT_OBJECT_0 + 2)
- return E_FAIL;
+ _canWrite_Semaphore.Lock();
+ // _bufSize : is remain size that was not read
size -= _bufSize;
+
+ // size : is size of data that was read
if (size != 0)
{
+ // if some data was read, then we report that size and return
if (processedSize)
*processedSize = size;
return S_OK;
}
- // if (waitResult == WAIT_OBJECT_0 + 1)
- _readingWasClosed2 = true;
+ _readingWasClosed2 = true;
}
// WritingWasCut = true;