Commit 374fea0a authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

qmgr: Add infrastructure for background file transferring.

parent a7ebdf2e
...@@ -139,6 +139,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume( ...@@ -139,6 +139,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
&& This->state != BG_JOB_STATE_TRANSFERRING) && This->state != BG_JOB_STATE_TRANSFERRING)
{ {
This->state = BG_JOB_STATE_QUEUED; This->state = BG_JOB_STATE_QUEUED;
SetEvent(globalMgr.jobEvent);
} }
LeaveCriticalSection(&globalMgr.cs); LeaveCriticalSection(&globalMgr.cs);
......
...@@ -130,6 +130,7 @@ static const IBackgroundCopyManagerVtbl BITS_IBackgroundCopyManager_Vtbl = ...@@ -130,6 +130,7 @@ static const IBackgroundCopyManagerVtbl BITS_IBackgroundCopyManager_Vtbl =
BackgroundCopyManagerImpl globalMgr = { BackgroundCopyManagerImpl globalMgr = {
&BITS_IBackgroundCopyManager_Vtbl, &BITS_IBackgroundCopyManager_Vtbl,
{ NULL, -1, 0, 0, 0, 0 }, { NULL, -1, 0, 0, 0, 0 },
NULL,
LIST_INIT(globalMgr.jobs) LIST_INIT(globalMgr.jobs)
}; };
...@@ -140,3 +141,59 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj) ...@@ -140,3 +141,59 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj)
*ppObj = (IBackgroundCopyManager *) &globalMgr; *ppObj = (IBackgroundCopyManager *) &globalMgr;
return S_OK; 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);
}
}
}
...@@ -81,8 +81,9 @@ typedef struct ...@@ -81,8 +81,9 @@ typedef struct
typedef struct typedef struct
{ {
const IBackgroundCopyManagerVtbl *lpVtbl; const IBackgroundCopyManagerVtbl *lpVtbl;
/* Protects job list and job states */ /* Protects job list, job states, and jobEvent */
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
HANDLE jobEvent;
struct list jobs; struct list jobs;
} BackgroundCopyManagerImpl; } BackgroundCopyManagerImpl;
...@@ -91,6 +92,7 @@ typedef struct ...@@ -91,6 +92,7 @@ typedef struct
const IClassFactoryVtbl *lpVtbl; const IClassFactoryVtbl *lpVtbl;
} ClassFactoryImpl; } ClassFactoryImpl;
extern HANDLE stop_event;
extern ClassFactoryImpl BITS_ClassFactory; extern ClassFactoryImpl BITS_ClassFactory;
extern BackgroundCopyManagerImpl globalMgr; extern BackgroundCopyManagerImpl globalMgr;
...@@ -104,6 +106,7 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner, ...@@ -104,6 +106,7 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
LPVOID *ppObj); LPVOID *ppObj);
HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj, HRESULT EnumBackgroundCopyFilesConstructor(LPVOID *ppObj,
IBackgroundCopyJob* copyJob); IBackgroundCopyJob* copyJob);
DWORD WINAPI fileTransfer(void *param);
/* Little helper functions */ /* Little helper functions */
static inline char * static inline char *
......
...@@ -28,10 +28,11 @@ ...@@ -28,10 +28,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(qmgr); WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
HANDLE stop_event = NULL;
static WCHAR qmgr_nameW[] = {'B','I','T','S',0}; static WCHAR qmgr_nameW[] = {'B','I','T','S',0};
static SERVICE_STATUS_HANDLE status_handle; static SERVICE_STATUS_HANDLE status_handle;
static SERVICE_STATUS status; static SERVICE_STATUS status;
static HANDLE stop_event = NULL;
static VOID static VOID
UpdateStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) UpdateStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
...@@ -108,6 +109,8 @@ StartCount(void) ...@@ -108,6 +109,8 @@ StartCount(void)
VOID WINAPI VOID WINAPI
ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv) ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
{ {
HANDLE fileTxThread;
DWORD threadId;
TRACE("\n"); TRACE("\n");
stop_event = CreateEventW(NULL, TRUE, FALSE, NULL); stop_event = CreateEventW(NULL, TRUE, FALSE, NULL);
...@@ -129,9 +132,24 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv) ...@@ -129,9 +132,24 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
return; 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); UpdateStatus(SERVICE_RUNNING, NO_ERROR, 0);
WaitForSingleObject(stop_event, INFINITE); WaitForSingleObject(fileTxThread, INFINITE);
UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0); UpdateStatus(SERVICE_STOPPED, NO_ERROR, 0);
CloseHandle(stop_event); CloseHandle(stop_event);
TRACE("service stoped\n"); TRACE("service stoped\n");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment