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