Dan Hipschman : qmgr: Add infrastructure for background file transferring.
Alexandre Julliard
julliard at winehq.org
Fri Mar 14 08:29:23 CDT 2008
Module: wine
Branch: master
Commit: 374fea0a71cd7f141f491ec0abee9b5f14168d4a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=374fea0a71cd7f141f491ec0abee9b5f14168d4a
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Thu Mar 13 15:54:01 2008 -0700
qmgr: Add infrastructure for background file transferring.
---
dlls/qmgr/job.c | 1 +
dlls/qmgr/qmgr.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/qmgr/qmgr.h | 5 +++-
dlls/qmgr/service.c | 22 +++++++++++++++++-
4 files changed, 82 insertions(+), 3 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..608e01a 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,59 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj)
*ppObj = (IBackgroundCopyManager *) &globalMgr;
return S_OK;
}
+
+DWORD WINAPI fileTransfer(void *param)
+{
+ BackgroundCopyManagerImpl *qmgr = &globalMgr;
+ HANDLE events[2];
+
+ events[0] = stop_event;
+ events[1] = qmgr->jobEvent;
+
+ for (;;)
+ {
+ BackgroundCopyJobImpl *job, *jobCur;
+ BOOL haveJob = FALSE;
+
+ /* Check if it's the stop_event */
+ if (WaitForMultipleObjects(2, events, FALSE, INFINITE) == WAIT_OBJECT_0)
+ return 0;
+
+ /* 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..fce84d9 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;
@@ -91,6 +92,7 @@ typedef struct
const IClassFactoryVtbl *lpVtbl;
} ClassFactoryImpl;
+extern HANDLE stop_event;
extern ClassFactoryImpl BITS_ClassFactory;
extern BackgroundCopyManagerImpl globalMgr;
@@ -104,6 +106,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..50d5156 100644
--- a/dlls/qmgr/service.c
+++ b/dlls/qmgr/service.c
@@ -28,10 +28,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
+HANDLE stop_event = NULL;
+
static WCHAR qmgr_nameW[] = {'B','I','T','S',0};
static SERVICE_STATUS_HANDLE status_handle;
static SERVICE_STATUS status;
-static HANDLE stop_event = NULL;
static VOID
UpdateStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
@@ -108,6 +109,8 @@ StartCount(void)
VOID WINAPI
ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
{
+ HANDLE fileTxThread;
+ DWORD threadId;
TRACE("\n");
stop_event = CreateEventW(NULL, TRUE, FALSE, NULL);
@@ -129,9 +132,24 @@ 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);
+ WaitForSingleObject(fileTxThread, INFINITE);
UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
CloseHandle(stop_event);
TRACE("service stoped\n");
More information about the wine-cvs
mailing list