[1/5] qmgr: Add infrastructure for background file transferring. [take 2]
Dan Hipschman
dsh at linux.ucla.edu
Mon Mar 10 18:31:23 CDT 2008
This doesn't use IEnumBackgroundCopyJobs like the last attempt. It just
traverses the list of jobs directly.
---
dlls/qmgr/qmgr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
dlls/qmgr/qmgr.h | 1 +
dlls/qmgr/service.c | 10 ++++++++++
3 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c
index c6fbc42..1218870 100644
--- a/dlls/qmgr/qmgr.c
+++ b/dlls/qmgr/qmgr.c
@@ -140,3 +140,47 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj)
*ppObj = (IBackgroundCopyManager *) &globalMgr;
return S_OK;
}
+
+DWORD WINAPI fileTransfer(void *param)
+{
+ BackgroundCopyManagerImpl *qmgr = &globalMgr;
+ BackgroundCopyJobImpl *job = NULL;
+
+ for (;;)
+ {
+ /* Note that other threads may add files to the job list, but only
+ this thread ever deletes them so we don't need to worry about jobs
+ magically disappearing from the list. */
+ EnterCriticalSection(&qmgr->cs);
+ {
+ struct list *next = (job
+ ? list_next(&qmgr->jobs, &job->entryFromQmgr)
+ : list_head(&qmgr->jobs));
+ job = (next
+ ? LIST_ENTRY(next, BackgroundCopyJobImpl, entryFromQmgr)
+ : NULL);
+ }
+ LeaveCriticalSection(&qmgr->cs);
+
+ if (job)
+ {
+ /* It's fine to access the job state outside of the job's critical
+ section in these cases because this thread is the only one that
+ can change the state once it gets in one of these. */
+ if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
+ {
+ EnterCriticalSection(&qmgr->cs);
+ list_remove(&job->entryFromQmgr);
+ job->lpVtbl->Release((IBackgroundCopyJob *) job);
+ LeaveCriticalSection(&qmgr->cs);
+ job = NULL;
+ }
+ else
+ {
+ /* Process job */
+ }
+ }
+ else
+ Sleep(1000);
+ }
+}
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index 166ee40..8931101 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -98,6 +98,7 @@ HRESULT BackgroundCopyFileConstructor(LPCWSTR remoteName,
LPCWSTR localName, LPVOID *ppObj);
HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj,
IBackgroundCopyJob* copyJob);
+DWORD WINAPI fileTransfer(void *param);
/* Little helper functions */
static inline char *
diff --git a/dlls/qmgr/service.c b/dlls/qmgr/service.c
index 5e31b8f..ac41988 100644
--- a/dlls/qmgr/service.c
+++ b/dlls/qmgr/service.c
@@ -108,6 +108,8 @@ StartCount(void)
VOID WINAPI
ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
{
+ HANDLE fileTxThread;
+ DWORD threadId;
TRACE("\n");
stop_event = CreateEventW(NULL, TRUE, FALSE, NULL);
@@ -129,6 +131,14 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
return;
}
+ fileTxThread = CreateThread(NULL, 0, fileTransfer, NULL, 0, &threadId);
+ if (!fileTxThread)
+ {
+ ERR("Failed starting file transfer thread\n");
+ UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
+ return;
+ }
+
UpdateStatus(SERVICE_RUNNING, NO_ERROR, 0);
WaitForSingleObject(stop_event, INFINITE);
More information about the wine-patches
mailing list