Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/schedsvc/atsvc.c | 22 +++++++++++++++++----- dlls/schedsvc/schedsvc_private.h | 1 + dlls/schedsvc/svc_main.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c index 542dfc3701..61771d87b3 100644 --- a/dlls/schedsvc/atsvc.c +++ b/dlls/schedsvc/atsvc.c @@ -76,6 +76,23 @@ static CRITICAL_SECTION_DEBUG cs_debug = }; static CRITICAL_SECTION at_job_list_section = { &cs_debug, -1, 0, 0, 0, 0 };
+void check_task_state(void) +{ + struct job_t *job; + + EnterCriticalSection(&at_job_list_section); + + LIST_FOR_EACH_ENTRY(job, &at_job_list, struct job_t, entry) + { + if (job->data.flags & 0x08000000) + FIXME("Terminate(%s): not implemented\n", debugstr_w(job->info.Command)); + else if (job->data.flags & 0x04000000) + FIXME("Run(%s): not implemented\n", debugstr_w(job->info.Command)); + } + + LeaveCriticalSection(&at_job_list_section); +} + static DWORD load_unicode_strings(const char *data, DWORD limit, AT_ENUM *info) { DWORD i, data_size = 0; @@ -340,11 +357,6 @@ void add_job(const WCHAR *name) return; }
- if (job->data.flags & 0x08000000) - FIXME("Terminate(%s): not implemented\n", debugstr_w(job->info.Command)); - else if (job->data.flags & 0x04000000) - FIXME("Run(%s): not implemented\n", debugstr_w(job->info.Command)); - EnterCriticalSection(&at_job_list_section); job->name = heap_strdupW(name); job->info.JobId = current_jobid++; diff --git a/dlls/schedsvc/schedsvc_private.h b/dlls/schedsvc/schedsvc_private.h index 215bba003e..df7144431d 100644 --- a/dlls/schedsvc/schedsvc_private.h +++ b/dlls/schedsvc/schedsvc_private.h @@ -25,6 +25,7 @@ void schedsvc_auto_start(void) DECLSPEC_HIDDEN; void add_job(const WCHAR *name) DECLSPEC_HIDDEN; void remove_job(const WCHAR *name) DECLSPEC_HIDDEN; +void check_task_state(void) DECLSPEC_HIDDEN;
static inline WCHAR *heap_strdupW(const WCHAR *src) { diff --git a/dlls/schedsvc/svc_main.c b/dlls/schedsvc/svc_main.c index f021d63b98..905582daf1 100644 --- a/dlls/schedsvc/svc_main.c +++ b/dlls/schedsvc/svc_main.c @@ -40,11 +40,27 @@ static DWORD WINAPI tasks_monitor_thread(void *arg) { static const WCHAR tasksW[] = { '\','T','a','s','k','s','\',0 }; WCHAR path[MAX_PATH]; - HANDLE htasks; + HANDLE htasks, timer; + LARGE_INTEGER period; OVERLAPPED ov;
TRACE("Starting...\n");
+ timer = CreateWaitableTimerW(NULL, FALSE, NULL); + if (timer == NULL) + { + ERR("CreateWaitableTimer failed\n"); + return -1; + } + + /* check the state of the tasks every 10 seconds */ + period.QuadPart = 10 * 1000; + if (!SetWaitableTimer(timer, &period, period.QuadPart, NULL, NULL, FALSE)) + { + ERR("SetWaitableTimer failed\n"); + return -1; + } + GetWindowsDirectoryW(path, MAX_PATH); lstrcatW(path, tasksW);
@@ -69,7 +85,7 @@ static DWORD WINAPI tasks_monitor_thread(void *arg) FILE_NOTIFY_INFORMATION data; WCHAR name_buffer[MAX_PATH]; } info; - HANDLE events[2]; + HANDLE events[3]; DWORD ret;
/* the buffer must be DWORD aligned */ @@ -87,10 +103,17 @@ static DWORD WINAPI tasks_monitor_thread(void *arg)
events[0] = done_event; events[1] = ov.hEvent; + events[2] = timer;
- ret = WaitForMultipleObjects(2, events, FALSE, INFINITE); + ret = WaitForMultipleObjects(3, events, FALSE, INFINITE); if (ret == WAIT_OBJECT_0) break;
+ if (ret == WAIT_OBJECT_0 + 2) + { + check_task_state(); + continue; + } + info.data.FileName[info.data.FileNameLength/sizeof(WCHAR)] = 0;
switch (info.data.Action) @@ -128,6 +151,8 @@ static DWORD WINAPI tasks_monitor_thread(void *arg) } }
+ CancelWaitableTimer(timer); + CloseHandle(timer); CloseHandle(ov.hEvent); CloseHandle(htasks);
Dmitry Timoshkov dmitry@baikal.ru writes:
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru
dlls/schedsvc/atsvc.c | 22 +++++++++++++++++----- dlls/schedsvc/schedsvc_private.h | 1 + dlls/schedsvc/svc_main.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 8 deletions(-)
Polling is usually not a good idea, especially for mobile devices. It would be better to trigger a wake up when something has changed. It looks to me like job flag changes in particular wouldn't need any polling.
If polling is necessary, for instance if there are more that MAXIMUM_WAIT_OBJECTS processes that you need to wait on for termination, it should be enabled only at that time.