[3/3] qmgr: Add critical sections for BackgroundCopyJobs.

Dan Hipschman dsh at linux.ucla.edu
Wed Mar 5 20:02:17 CST 2008


Adds critical sections for jobs.  These are needed on state, file list, and
progress updates.  I went with one CS per job rather than three, one for
each of the above fields.  This is going to be necessary before we actually
start downloading anything in another thread.

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

diff --git a/dlls/qmgr/enum_files.c b/dlls/qmgr/enum_files.c
index 082b541..36afc33 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;
+    EnterCriticalSection(&job->cs);
     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)
         {
+            LeaveCriticalSection(&job->cs);
             HeapFree(GetProcessHeap(), 0, This);
             return E_OUTOFMEMORY;
         }
@@ -206,6 +208,7 @@ HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj, IBackgroundCopyJob* iC
         This->files[i] = (IBackgroundCopyFile *) file;
         ++i;
     }
+    LeaveCriticalSection(&job->cs);
 
     *ppObj = &This->lpVtbl;
     return S_OK;
diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c
index 2a894ba..7112d43 100644
--- a/dlls/qmgr/job.c
+++ b/dlls/qmgr/job.c
@@ -95,8 +95,10 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
     /* Add a reference to the file to file list */
     IBackgroundCopyFile_AddRef(pFile);
     file = (BackgroundCopyFileImpl *) pFile;
+    EnterCriticalSection(&This->cs);
     list_add_head(&This->files, &file->entryFromJob);
     ++This->jobProgress.FilesTotal;
+    LeaveCriticalSection(&This->cs);
 
     return S_OK;
 }
@@ -120,24 +122,26 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
     IBackgroundCopyJob* iface)
 {
     BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
+    HRESULT rv = S_OK;
 
+    EnterCriticalSection(&This->cs);
     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;
+    }
+    LeaveCriticalSection(&This->cs);
 
-    This->state = BG_JOB_STATE_QUEUED;
-    return S_OK;
+    return rv;
 }
 
 static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
@@ -185,10 +189,12 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
     if (!pVal)
         return E_INVALIDARG;
 
+    EnterCriticalSection(&This->cs);
     pVal->BytesTotal = This->jobProgress.BytesTotal;
     pVal->BytesTransferred = This->jobProgress.BytesTransferred;
     pVal->FilesTotal = This->jobProgress.FilesTotal;
     pVal->FilesTransferred = This->jobProgress.FilesTransferred;
+    LeaveCriticalSection(&This->cs);
 
     return S_OK;
 }
@@ -210,6 +216,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
     if (!pVal)
         return E_INVALIDARG;
 
+    /* Don't think we need a critical section for this */
     *pVal = This->state;
     return S_OK;
 }
@@ -441,6 +448,7 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
         return E_OUTOFMEMORY;
 
     This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
+    InitializeCriticalSection(&This->cs);
     This->ref = 1;
     This->type = type;
 
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index d03724a..3fcbd64 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;
+    CRITICAL_SECTION cs;
     struct list entryFromQmgr;
 } BackgroundCopyJobImpl;
 



More information about the wine-patches mailing list