[1/4] qmgr: Add critical sections for Jobs and Files. [take 2]

Dan Hipschman dsh at linux.ucla.edu
Wed Mar 12 13:56:13 CDT 2008


Using COM macros instead of direct access to the vtbl.

---
 dlls/qmgr/enum_files.c |    3 +++
 dlls/qmgr/file.c       |   10 ++++++++--
 dlls/qmgr/job.c        |   33 ++++++++++++++++++++++-----------
 dlls/qmgr/qmgr.c       |    2 +-
 dlls/qmgr/qmgr.h       |   10 ++++++++--
 5 files changed, 42 insertions(+), 16 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/file.c b/dlls/qmgr/file.c
index 93ffba4..f1ae06a 100644
--- a/dlls/qmgr/file.c
+++ b/dlls/qmgr/file.c
@@ -25,6 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
 
 static void BackgroundCopyFileDestructor(BackgroundCopyFileImpl *This)
 {
+    IBackgroundCopyJob_Release((IBackgroundCopyJob *) This->owner);
     HeapFree(GetProcessHeap(), 0, This->info.LocalName);
     HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
     HeapFree(GetProcessHeap(), 0, This);
@@ -105,9 +106,11 @@ static HRESULT WINAPI BITS_IBackgroundCopyFile_GetProgress(
 {
     BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;
 
+    EnterCriticalSection(&This->owner->cs);
     pVal->BytesTotal = This->fileProgress.BytesTotal;
     pVal->BytesTransferred = This->fileProgress.BytesTransferred;
     pVal->Completed = This->fileProgress.Completed;
+    LeaveCriticalSection(&This->owner->cs);
 
     return S_OK;
 }
@@ -122,8 +125,9 @@ static const IBackgroundCopyFileVtbl BITS_IBackgroundCopyFile_Vtbl =
     BITS_IBackgroundCopyFile_GetProgress
 };
 
-HRESULT BackgroundCopyFileConstructor(LPCWSTR remoteName,
-                                      LPCWSTR localName, LPVOID *ppObj)
+HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
+                                      LPCWSTR remoteName, LPCWSTR localName,
+                                      LPVOID *ppObj)
 {
     BackgroundCopyFileImpl *This;
     int n;
@@ -160,6 +164,8 @@ HRESULT BackgroundCopyFileConstructor(LPCWSTR remoteName,
     This->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
     This->fileProgress.BytesTransferred = 0;
     This->fileProgress.Completed = FALSE;
+    This->owner = owner;
+    IBackgroundCopyJob_AddRef((IBackgroundCopyJob *) owner);
 
     *ppObj = &This->lpVtbl;
     return S_OK;
diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c
index 8768027..6bc63f4 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)
 {
+    DeleteCriticalSection(&This->cs);
     HeapFree(GetProcessHeap(), 0, This->displayName);
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -88,15 +89,17 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
     /* We should return E_INVALIDARG in these cases.  */
     FIXME("Check for valid filenames and supported protocols\n");
 
-    res = BackgroundCopyFileConstructor(RemoteUrl, LocalName, (LPVOID *) &pFile);
+    res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, (LPVOID *) &pFile);
     if (res != S_OK)
         return res;
 
     /* 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 +123,26 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
     IBackgroundCopyJob* iface)
 {
     BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
+    HRESULT rv = S_OK;
 
+    EnterCriticalSection(&globalMgr.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(&globalMgr.cs);
 
-    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;
 
+    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 +217,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 +449,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;
 
@@ -448,6 +457,7 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
     This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
     if (!This->displayName)
     {
+        DeleteCriticalSection(&This->cs);
         HeapFree(GetProcessHeap(), 0, This);
         return E_OUTOFMEMORY;
     }
@@ -456,6 +466,7 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
     hr = CoCreateGuid(&This->jobId);
     if (FAILED(hr))
     {
+        DeleteCriticalSection(&This->cs);
         HeapFree(GetProcessHeap(), 0, This->displayName);
         HeapFree(GetProcessHeap(), 0, This);
         return hr;
diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c
index c6fbc42..b0a6013 100644
--- a/dlls/qmgr/qmgr.c
+++ b/dlls/qmgr/qmgr.c
@@ -127,7 +127,7 @@ static const IBackgroundCopyManagerVtbl BITS_IBackgroundCopyManager_Vtbl =
     BITS_IBackgroundCopyManager_GetErrorDescription
 };
 
-static BackgroundCopyManagerImpl globalMgr = {
+BackgroundCopyManagerImpl globalMgr = {
     &BITS_IBackgroundCopyManager_Vtbl,
     { NULL, -1, 0, 0, 0, 0 },
     LIST_INIT(globalMgr.jobs)
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index 166ee40..a584694 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -41,6 +41,8 @@ typedef struct
     struct list files;
     BG_JOB_PROGRESS jobProgress;
     BG_JOB_STATE state;
+    /* Protects file list, and progress */
+    CRITICAL_SECTION cs;
     struct list entryFromQmgr;
 } BackgroundCopyJobImpl;
 
@@ -72,12 +74,14 @@ typedef struct
     BG_FILE_INFO info;
     BG_FILE_PROGRESS fileProgress;
     struct list entryFromJob;
+    BackgroundCopyJobImpl *owner;
 } BackgroundCopyFileImpl;
 
 /* Background copy manager vtbl and related data */
 typedef struct
 {
     const IBackgroundCopyManagerVtbl *lpVtbl;
+    /* Protects job list and job states */
     CRITICAL_SECTION cs;
     struct list jobs;
 } BackgroundCopyManagerImpl;
@@ -88,14 +92,16 @@ typedef struct
 } ClassFactoryImpl;
 
 extern ClassFactoryImpl BITS_ClassFactory;
+extern BackgroundCopyManagerImpl globalMgr;
 
 HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj);
 HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
                                      GUID *pJobId, LPVOID *ppObj);
 HRESULT EnumBackgroundCopyJobsConstructor(LPVOID *ppObj,
                                           IBackgroundCopyManager* copyManager);
-HRESULT BackgroundCopyFileConstructor(LPCWSTR remoteName,
-                                      LPCWSTR localName, LPVOID *ppObj);
+HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
+                                      LPCWSTR remoteName, LPCWSTR localName,
+                                      LPVOID *ppObj);
 HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj,
                                            IBackgroundCopyJob* copyJob);
 



More information about the wine-patches mailing list