Vincent Povirk : windowscodecs: Add locking to StreamOnMemory.

Alexandre Julliard julliard at winehq.org
Mon Apr 12 09:54:07 CDT 2010


Module: wine
Branch: master
Commit: 40d48e674e5d3233ce3edb38cc16ccecb7edc1d0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=40d48e674e5d3233ce3edb38cc16ccecb7edc1d0

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Fri Apr  9 10:53:24 2010 -0500

windowscodecs: Add locking to StreamOnMemory.

---

 dlls/windowscodecs/stream.c |   52 ++++++++++++++++++++++++++++++++----------
 1 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/dlls/windowscodecs/stream.c b/dlls/windowscodecs/stream.c
index c59a9d2..f3be0c3 100644
--- a/dlls/windowscodecs/stream.c
+++ b/dlls/windowscodecs/stream.c
@@ -41,6 +41,8 @@ typedef struct StreamOnMemory {
     BYTE *pbMemory;
     DWORD dwMemsize;
     DWORD dwCurPos;
+
+    CRITICAL_SECTION lock; /* must be held when pbMemory or dwCurPos is accessed */
 } StreamOnMemory;
 
 static HRESULT WINAPI StreamOnMemory_QueryInterface(IStream *iface,
@@ -82,6 +84,8 @@ static ULONG WINAPI StreamOnMemory_Release(IStream *iface)
     TRACE("(%p) refcount=%u\n", iface, ref);
 
     if (ref == 0) {
+        This->lock.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&This->lock);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -96,9 +100,12 @@ static HRESULT WINAPI StreamOnMemory_Read(IStream *iface,
 
     if (!pv) return E_INVALIDARG;
 
+    EnterCriticalSection(&This->lock);
     uBytesRead = min(cb, This->dwMemsize - This->dwCurPos);
     memcpy(pv, This->pbMemory + This->dwCurPos, uBytesRead);
     This->dwCurPos += uBytesRead;
+    LeaveCriticalSection(&This->lock);
+
     if (pcbRead) *pcbRead = uBytesRead;
 
     return S_OK;
@@ -108,18 +115,26 @@ static HRESULT WINAPI StreamOnMemory_Write(IStream *iface,
     void const *pv, ULONG cb, ULONG *pcbWritten)
 {
     StreamOnMemory *This = (StreamOnMemory*)iface;
+    HRESULT hr;
     TRACE("(%p)\n", This);
 
     if (!pv) return E_INVALIDARG;
 
-    if (cb > This->dwMemsize - This->dwCurPos) return STG_E_MEDIUMFULL;
-    if (cb) {
-        memcpy(This->pbMemory + This->dwCurPos, pv, cb);
-        This->dwCurPos += cb;
+    EnterCriticalSection(&This->lock);
+    if (cb > This->dwMemsize - This->dwCurPos) {
+        hr = STG_E_MEDIUMFULL;
+    }
+    else {
+        if (cb) {
+            memcpy(This->pbMemory + This->dwCurPos, pv, cb);
+            This->dwCurPos += cb;
+            hr = S_OK;
+        }
+        if (pcbWritten) *pcbWritten = cb;
     }
-    if (pcbWritten) *pcbWritten = cb;
+    LeaveCriticalSection(&This->lock);
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
@@ -127,20 +142,29 @@ static HRESULT WINAPI StreamOnMemory_Seek(IStream *iface,
 {
     StreamOnMemory *This = (StreamOnMemory*)iface;
     LARGE_INTEGER NewPosition;
+    HRESULT hr=S_OK;
     TRACE("(%p)\n", This);
 
+    EnterCriticalSection(&This->lock);
     if (dwOrigin == STREAM_SEEK_SET) NewPosition.QuadPart = dlibMove.QuadPart;
     else if (dwOrigin == STREAM_SEEK_CUR) NewPosition.QuadPart = This->dwCurPos + dlibMove.QuadPart;
     else if (dwOrigin == STREAM_SEEK_END) NewPosition.QuadPart = This->dwMemsize + dlibMove.QuadPart;
-    else return E_INVALIDARG;
+    else hr = E_INVALIDARG;
 
-    if (NewPosition.u.HighPart) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
-    if (NewPosition.QuadPart > This->dwMemsize) return E_INVALIDARG;
-    if (NewPosition.QuadPart < 0) return E_INVALIDARG;
-    This->dwCurPos = NewPosition.u.LowPart;
+    if (SUCCEEDED(hr)) {
+        if (NewPosition.u.HighPart) hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
+        else if (NewPosition.QuadPart > This->dwMemsize) hr = E_INVALIDARG;
+        else if (NewPosition.QuadPart < 0) hr = E_INVALIDARG;
+    }
 
-    if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
-    return S_OK;
+    if (SUCCEEDED(hr)) {
+        This->dwCurPos = NewPosition.u.LowPart;
+
+        if(plibNewPosition) plibNewPosition->QuadPart = This->dwCurPos;
+    }
+    LeaveCriticalSection(&This->lock);
+
+    return hr;
 }
 
 /* SetSize isn't implemented in the native windowscodecs DLL either */
@@ -450,6 +474,8 @@ static HRESULT WINAPI IWICStreamImpl_InitializeFromMemory(IWICStream *iface,
     pObject->pbMemory = pbBuffer;
     pObject->dwMemsize = cbBufferSize;
     pObject->dwCurPos = 0;
+    InitializeCriticalSection(&pObject->lock);
+    pObject->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": StreamOnMemory.lock");
 
     This->pStream = (IStream*)pObject;
     return S_OK;




More information about the wine-cvs mailing list