qmgr: Add critical sections for jobs and files.
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 @@
/* 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 @@
This->numFiles * sizeof This->files[0]);
if (!This->files)
{
+ LeaveCriticalSection(&job->cs);
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
@@ -206,6 +208,7 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
static void BackgroundCopyJobDestructor(BackgroundCopyJobImpl *This)
{
+ DeleteCriticalSection(&This->cs);
HeapFree(GetProcessHeap(), 0, This->displayName);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -88,15 +89,17 @@
/* 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 @@
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 @@
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 @@
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 @@
return E_OUTOFMEMORY;
This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
+ InitializeCriticalSection(&This->cs);
This->ref = 1;
This->type = type;
@@ -448,6 +457,7 @@
This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
if (!This->displayName)
{
+ DeleteCriticalSection(&This->cs);
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
@@ -456,6 +466,7 @@
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 @@
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 @@
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 @@
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 @@
} 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);