Francois Gouget : mstask/tests: Work around race conditions with the task scheduler process.

Alexandre Julliard julliard at winehq.org
Fri May 21 14:19:44 CDT 2021


Module: wine
Branch: master
Commit: 2e6ae164692072abd1f4dc156581dc760f0a8046
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2e6ae164692072abd1f4dc156581dc760f0a8046

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Fri May 21 00:13:52 2021 +0200

mstask/tests: Work around race conditions with the task scheduler process.

When a task is created the process scheduler locks and loads it. This
can cause ITaskScheduler_Delete() to fail with a sharing violation if
it is called at the wrong time. Just retry a bit later when that
happens.

This fixes failures mostly in Wine but also in Windows 10 from time
to time in both task and task_scheduler.

Signed-off-by: Francois Gouget <fgouget at icodeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mstask/tests/task.c           |  7 +++++--
 dlls/mstask/tests/task_scheduler.c | 31 ++++++++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/dlls/mstask/tests/task.c b/dlls/mstask/tests/task.c
index a9957117e9b..0c7f85394ea 100644
--- a/dlls/mstask/tests/task.c
+++ b/dlls/mstask/tests/task.c
@@ -29,6 +29,9 @@ static ITaskScheduler *scheduler;
 static const WCHAR task_name[] = {'T','e','s','t','i','n','g',0};
 static const WCHAR empty[] = {0};
 
+extern HRESULT taskscheduler_delete(ITaskScheduler*, const WCHAR*);
+
+
 static LPCWSTR path_resolve_name(LPCWSTR base_name)
 {
     static WCHAR buffer[MAX_PATH];
@@ -552,7 +555,7 @@ static void test_Run(void)
     HRESULT hr, status;
 
     /* cleanup after previous runs */
-    ITaskScheduler_Delete(scheduler, wine_test_runW);
+    taskscheduler_delete(scheduler, wine_test_runW);
 
     hr = ITaskScheduler_NewWorkItem(scheduler, wine_test_runW, &CLSID_CTask,
                                     &IID_ITask, (IUnknown **)&task);
@@ -679,7 +682,7 @@ static void test_Run(void)
     else
         ITask_Release(task);
 
-    hr = ITaskScheduler_Delete(scheduler, wine_test_runW);
+    hr = taskscheduler_delete(scheduler, wine_test_runW);
     ok(hr == S_OK, "got %#x\n", hr);
 }
 
diff --git a/dlls/mstask/tests/task_scheduler.c b/dlls/mstask/tests/task_scheduler.c
index 5abee75e23c..fafad585f53 100644
--- a/dlls/mstask/tests/task_scheduler.c
+++ b/dlls/mstask/tests/task_scheduler.c
@@ -31,6 +31,27 @@ static ITaskScheduler *test_task_scheduler;
 
 static const WCHAR does_not_existW[] = {'\\','\\','d','o','e','s','_','n','o','t','_','e','x','i','s','t',0};
 
+
+HRESULT taskscheduler_delete(ITaskScheduler *scheduler, const WCHAR *name)
+{
+    HRESULT hr;
+    int i = 0;
+
+    while (1)
+    {
+        hr = ITaskScheduler_Delete(scheduler, name);
+        if (hr != HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION)) break;
+        if (++i == 5) break;
+
+        /* The task scheduler locked the file to load the task (see
+         * ITaskScheduler_Activate()). It should be done soon.
+         */
+        trace("Got a sharing violation deleting %s, retrying...\n", wine_dbgstr_w(name));
+        Sleep(100);
+    }
+    return hr;
+}
+
 static void test_NewWorkItem(void)
 {
     HRESULT hres;
@@ -225,7 +246,7 @@ static void test_Enum(void)
     ok(hr == S_OK, "got %#x\n", hr);
 
     /* cleanup after previous runs */
-    ITaskScheduler_Delete(scheduler, Task1);
+    taskscheduler_delete(scheduler, Task1);
 
     hr = ITaskScheduler_NewWorkItem(scheduler, Task1, &CLSID_CTask, &IID_ITask, (IUnknown **)&task);
     ok(hr == S_OK, "got %#x\n", hr);
@@ -291,7 +312,7 @@ static void test_Enum(void)
 
     IEnumWorkItems_Release(tasks);
 
-    hr = ITaskScheduler_Delete(scheduler, Task1);
+    hr = taskscheduler_delete(scheduler, Task1);
     ok(hr == S_OK, "got %#x\n", hr);
 
     ITaskScheduler_Release(scheduler);
@@ -494,11 +515,11 @@ static void test_task_storage(void)
 
     test_save_task_curfile(task);
 
-    hr = ITaskScheduler_Delete(scheduler, Task1);
+    hr = taskscheduler_delete(scheduler, Task1);
     ok(hr == S_OK, "got %#x\n", hr);
-    hr = ITaskScheduler_Delete(scheduler, Task2);
+    hr = taskscheduler_delete(scheduler, Task2);
     ok(hr == S_OK, "got %#x\n", hr);
-    hr = ITaskScheduler_Delete(scheduler, Task3);
+    hr = taskscheduler_delete(scheduler, Task3);
     ok(hr == S_OK, "got %#x\n", hr);
 
     ITask_Release(task);




More information about the wine-cvs mailing list