From 2e6ae164692072abd1f4dc156581dc760f0a8046 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Fri, 21 May 2021 00:13:52 +0200 Subject: [PATCH] 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 Signed-off-by: Alexandre Julliard --- 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);