[3/6] qmgr: Add a mutex to BackgroundCopyJob.

Dan Hipschman dsh at linux.ucla.edu
Thu Mar 6 21:05:52 CST 2008


Pretty much the same as yesterday but I changed to using mutexes instead
of critical sections since I need to wait on two at once (one for the
job and the other for the file when updating progress).

---
 dlls/qmgr/enum_files.c |    3 +++
 dlls/qmgr/job.c        |   36 ++++++++++++++++++++++++++----------
 dlls/qmgr/qmgr.h       |    1 +
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/dlls/qmgr/enum_files.c b/dlls/qmgr/enum_files.c
index 082b541..f5c22ad 100644
--- a/dlls/qmgr/enum_files.c
+++ b/dlls/qmgr/enum_files.c
@@ -186,6 +186,7 @@ HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj, IBackgroundCopyJob* iC
 
     /* Create array of files */
     This->indexFiles = 0;
+    WaitForSingleObject(job->mutex, INFINITE);
     This->numFiles = list_count(&job->files);
     This->files = NULL;
     if (This->numFiles > 0)
@@ -194,6 +195,7 @@ HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj, IBackgroundCopyJob* iC
                                 This->numFiles * sizeof This->files[0]);
         if (!This->files)
         {
+            ReleaseMutex(job->mutex);
             HeapFree(GetProcessHeap(), 0, This);
             return E_OUTOFMEMORY;
         }
@@ -206,6 +208,7 @@ HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj, IBackgroundCopyJob* iC
         This->files[i] = (IBackgroundCopyFile *) file;
         ++i;
     }
+    ReleaseMutex(job->mutex);
 
     *ppObj = &This->lpVtbl;
     return S_OK;
diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c
index 2a894ba..e8158a2 100644
--- a/dlls/qmgr/job.c
+++ b/dlls/qmgr/job.c
@@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
 
 static void BackgroundCopyJobDestructor(BackgroundCopyJobImpl *This)
 {
+    CloseHandle(This->mutex);
     HeapFree(GetProcessHeap(), 0, This->displayName);
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -95,8 +96,10 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
     /* Add a reference to the file to file list */
     IBackgroundCopyFile_AddRef(pFile);
     file = (BackgroundCopyFileImpl *) pFile;
+    WaitForSingleObject(This->mutex, INFINITE);
     list_add_head(&This->files, &file->entryFromJob);
     ++This->jobProgress.FilesTotal;
+    ReleaseMutex(This->mutex);
 
     return S_OK;
 }
@@ -120,24 +123,26 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
     IBackgroundCopyJob* iface)
 {
     BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
+    HRESULT rv = S_OK;
 
+    WaitForSingleObject(This->mutex, INFINITE);
     if (This->state == BG_JOB_STATE_CANCELLED
         || This->state == BG_JOB_STATE_ACKNOWLEDGED)
     {
-        return BG_E_INVALID_STATE;
+        rv = BG_E_INVALID_STATE;
     }
-
-    if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
-        return BG_E_EMPTY;
-
-    if (This->state == BG_JOB_STATE_CONNECTING
-        || This->state == BG_JOB_STATE_TRANSFERRING)
+    else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
     {
-        return S_OK;
+        rv = BG_E_EMPTY;
+    }
+    else if (This->state != BG_JOB_STATE_CONNECTING
+             && This->state != BG_JOB_STATE_TRANSFERRING)
+    {
+        This->state = BG_JOB_STATE_QUEUED;
     }
+    ReleaseMutex(This->mutex);
 
-    This->state = BG_JOB_STATE_QUEUED;
-    return S_OK;
+    return rv;
 }
 
 static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
@@ -185,10 +190,12 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
     if (!pVal)
         return E_INVALIDARG;
 
+    WaitForSingleObject(This->mutex, INFINITE);
     pVal->BytesTotal = This->jobProgress.BytesTotal;
     pVal->BytesTransferred = This->jobProgress.BytesTransferred;
     pVal->FilesTotal = This->jobProgress.FilesTotal;
     pVal->FilesTransferred = This->jobProgress.FilesTransferred;
+    ReleaseMutex(This->mutex);
 
     return S_OK;
 }
@@ -210,6 +217,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
     if (!pVal)
         return E_INVALIDARG;
 
+    /* Don't think we need the mutex for this */
     *pVal = This->state;
     return S_OK;
 }
@@ -441,6 +449,12 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
         return E_OUTOFMEMORY;
 
     This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
+    This->mutex = CreateMutexW(NULL, FALSE, NULL);
+    if (!This->mutex)
+    {
+        HeapFree(GetProcessHeap(), 0, This);
+        return E_OUTOFMEMORY;
+    }
     This->ref = 1;
     This->type = type;
 
@@ -448,6 +462,7 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
     This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
     if (!This->displayName)
     {
+        CloseHandle(This->mutex);
         HeapFree(GetProcessHeap(), 0, This);
         return E_OUTOFMEMORY;
     }
@@ -456,6 +471,7 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
     hr = CoCreateGuid(&This->jobId);
     if (FAILED(hr))
     {
+        CloseHandle(This->mutex);
         HeapFree(GetProcessHeap(), 0, This->displayName);
         HeapFree(GetProcessHeap(), 0, This);
         return hr;
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index 8931101..f3e22d3 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -41,6 +41,7 @@ typedef struct
     struct list files;
     BG_JOB_PROGRESS jobProgress;
     BG_JOB_STATE state;
+    HANDLE mutex;
     struct list entryFromQmgr;
 } BackgroundCopyJobImpl;
 



More information about the wine-patches mailing list