[2/4] qmgr: Add infrastructure for background file transferring. [take 4]
Dan Hipschman
dsh at linux.ucla.edu
Wed Mar 12 13:56:45 CDT 2008
Using COM macros instead of directly accessing the vtbl.
---
dlls/qmgr/job.c | 1 +
dlls/qmgr/qmgr.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/qmgr/qmgr.h | 4 +++-
dlls/qmgr/service.c | 17 +++++++++++++++++
4 files changed, 72 insertions(+), 1 deletions(-)
diff --git a/dlls/qmgr/job.c b/dlls/qmgr/job.c
index 6bc63f4..2fbf1bc 100644
--- a/dlls/qmgr/job.c
+++ b/dlls/qmgr/job.c
@@ -139,6 +139,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
&& This->state != BG_JOB_STATE_TRANSFERRING)
{
This->state = BG_JOB_STATE_QUEUED;
+ SetEvent(globalMgr.jobEvent);
}
LeaveCriticalSection(&globalMgr.cs);
diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c
index b0a6013..54b4973 100644
--- a/dlls/qmgr/qmgr.c
+++ b/dlls/qmgr/qmgr.c
@@ -130,6 +130,7 @@ static const IBackgroundCopyManagerVtbl BITS_IBackgroundCopyManager_Vtbl =
BackgroundCopyManagerImpl globalMgr = {
&BITS_IBackgroundCopyManager_Vtbl,
{ NULL, -1, 0, 0, 0, 0 },
+ NULL,
LIST_INIT(globalMgr.jobs)
};
@@ -140,3 +141,53 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj)
*ppObj = (IBackgroundCopyManager *) &globalMgr;
return S_OK;
}
+
+DWORD WINAPI fileTransfer(void *param)
+{
+ BackgroundCopyManagerImpl *qmgr = &globalMgr;
+
+ for (;;)
+ {
+ BackgroundCopyJobImpl *job, *jobCur;
+ BOOL haveJob = FALSE;
+
+ WaitForSingleObject(qmgr->jobEvent, INFINITE);
+
+ /* 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);
+
+ LIST_FOR_EACH_ENTRY_SAFE(job, jobCur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr)
+ {
+ if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
+ {
+ list_remove(&job->entryFromQmgr);
+ IBackgroundCopyJob_Release((IBackgroundCopyJob *) job);
+ }
+ else if (job->state == BG_JOB_STATE_QUEUED)
+ {
+ haveJob = TRUE;
+ break;
+ }
+ else if (job->state == BG_JOB_STATE_CONNECTING
+ || job->state == BG_JOB_STATE_TRANSFERRING)
+ {
+ ERR("Invalid state for job %p: %d\n", job, job->state);
+ }
+ }
+
+ if (!haveJob)
+ ResetEvent(qmgr->jobEvent);
+
+ LeaveCriticalSection(&qmgr->cs);
+
+ if (haveJob)
+ {
+ FIXME("Actually process job %p; setting error state\n", job);
+ EnterCriticalSection(&qmgr->cs);
+ job->state = BG_JOB_STATE_ERROR;
+ LeaveCriticalSection(&qmgr->cs);
+ }
+ }
+}
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index a584694..96635a7 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -81,8 +81,9 @@ typedef struct
typedef struct
{
const IBackgroundCopyManagerVtbl *lpVtbl;
- /* Protects job list and job states */
+ /* Protects job list, job states, and jobEvent */
CRITICAL_SECTION cs;
+ HANDLE jobEvent;
struct list jobs;
} BackgroundCopyManagerImpl;
@@ -104,6 +105,7 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
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..553d43c 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,21 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
return;
}
+ globalMgr.jobEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if (!globalMgr.jobEvent) {
+ ERR("Couldn't create event: error %d\n", GetLastError());
+ UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
+ 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