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(
&& This->state != BG_JOB_STATE_TRANSFERRING)
{
This->state = BG_JOB_STATE_QUEUED;
SetEvent(globalMgr.jobEvent);
}
LeaveCriticalSection(&globalMgr.cs);
......
......@@ -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);
}
}
}
......@@ -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 *
......
......@@ -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");
......
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