[1/5] qmgr: Add infrastructure for background file transferring. [take 2]

Dan Hipschman dsh at linux.ucla.edu
Mon Mar 10 18:31:23 CDT 2008


This doesn't use IEnumBackgroundCopyJobs like the last attempt.  It just
traverses the list of jobs directly.

---
 dlls/qmgr/qmgr.c    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/qmgr/qmgr.h    |    1 +
 dlls/qmgr/service.c |   10 ++++++++++
 3 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/dlls/qmgr/qmgr.c b/dlls/qmgr/qmgr.c
index c6fbc42..1218870 100644
--- a/dlls/qmgr/qmgr.c
+++ b/dlls/qmgr/qmgr.c
@@ -140,3 +140,47 @@ HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj)
     *ppObj = (IBackgroundCopyManager *) &globalMgr;
     return S_OK;
 }
+
+DWORD WINAPI fileTransfer(void *param)
+{
+    BackgroundCopyManagerImpl *qmgr = &globalMgr;
+    BackgroundCopyJobImpl *job = NULL;
+
+    for (;;)
+    {
+        /* 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);
+        {
+            struct list *next = (job
+                                 ? list_next(&qmgr->jobs, &job->entryFromQmgr)
+                                 : list_head(&qmgr->jobs));
+            job = (next
+                   ? LIST_ENTRY(next, BackgroundCopyJobImpl, entryFromQmgr)
+                   : NULL);
+        }
+        LeaveCriticalSection(&qmgr->cs);
+
+        if (job)
+        {
+            /* It's fine to access the job state outside of the job's critical
+               section in these cases because this thread is the only one that
+               can change the state once it gets in one of these.  */
+            if (job->state == BG_JOB_STATE_ACKNOWLEDGED || job->state == BG_JOB_STATE_CANCELLED)
+            {
+                EnterCriticalSection(&qmgr->cs);
+                list_remove(&job->entryFromQmgr);
+                job->lpVtbl->Release((IBackgroundCopyJob *) job);
+                LeaveCriticalSection(&qmgr->cs);
+                job = NULL;
+            }
+            else
+            {
+                /* Process job */
+            }
+        }
+        else
+            Sleep(1000);
+    }
+}
diff --git a/dlls/qmgr/qmgr.h b/dlls/qmgr/qmgr.h
index 166ee40..8931101 100644
--- a/dlls/qmgr/qmgr.h
+++ b/dlls/qmgr/qmgr.h
@@ -98,6 +98,7 @@ HRESULT BackgroundCopyFileConstructor(LPCWSTR remoteName,
                                       LPCWSTR localName, 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..ac41988 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,14 @@ ServiceMain(DWORD dwArgc, LPWSTR *lpszArgv)
         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