diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c index 9bd1dece31..cfd63bfc68 100644 --- a/src/lib/ecore/ecore_exe.c +++ b/src/lib/ecore/ecore_exe.c @@ -33,6 +33,14 @@ struct _ecore_exe_dead_exe char *cmd; }; +#ifdef _WIN32 +/* + * this job is used to close child processes when parent one is closed + * see https://stackoverflow.com/a/53214/688348 + */ +HANDLE _ecore_exe_win32_job = NULL; +#endif + EAPI int ECORE_EXE_EVENT_ADD = 0; EAPI int ECORE_EXE_EVENT_DEL = 0; EAPI int ECORE_EXE_EVENT_DATA = 0; @@ -338,6 +346,21 @@ ecore_exe_hup(Ecore_Exe *obj) void _ecore_exe_init(void) { +#ifdef _WIN32 + _ecore_exe_win32_job = CreateJobObject( NULL, NULL); + if (_ecore_exe_win32_job) + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli; + + memset (&jeli, 0, sizeof(jeli)); + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if (!SetInformationJobObject(_ecore_exe_win32_job, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) + { + CloseHandle(_ecore_exe_win32_job); + _ecore_exe_win32_job = NULL; + } + } +#endif ECORE_EXE_EVENT_ADD = ecore_event_type_new(); ECORE_EXE_EVENT_DEL = ecore_event_type_new(); ECORE_EXE_EVENT_DATA = ecore_event_type_new(); @@ -358,6 +381,11 @@ _ecore_exe_shutdown(void) ECORE_EXE_EVENT_DEL, ECORE_EXE_EVENT_DATA, ECORE_EXE_EVENT_ERROR); + +#ifdef _WIN32 + if (_ecore_exe_win32_job) + CloseHandle(_ecore_exe_win32_job); +#endif } Ecore_Exe * diff --git a/src/lib/ecore/ecore_exe_private.h b/src/lib/ecore/ecore_exe_private.h index aad66fc1da..2dbaedecc5 100644 --- a/src/lib/ecore/ecore_exe_private.h +++ b/src/lib/ecore/ecore_exe_private.h @@ -133,6 +133,10 @@ struct _Ecore_Exe_Data typedef struct _Ecore_Exe_Data Ecore_Exe_Data; +#ifdef _WIN32 +extern HANDLE _ecore_exe_win32_job; +#endif + EAPI extern int ECORE_EXE_EVENT_ADD; EAPI extern int ECORE_EXE_EVENT_DEL; EAPI extern int ECORE_EXE_EVENT_DATA; diff --git a/src/lib/ecore/ecore_exe_win32.c b/src/lib/ecore/ecore_exe_win32.c index 24159c6eac..8002db20e3 100644 --- a/src/lib/ecore/ecore_exe_win32.c +++ b/src/lib/ecore/ecore_exe_win32.c @@ -512,6 +512,13 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe) goto error; } + if ((flags & ECORE_EXE_TERM_WITH_PARENT) && _ecore_exe_win32_job) + { + if (!AssignProcessToJobObject(_ecore_exe_win32_job, pi.hProcess)) + WRN("AssignProcessToJobObject failed (job: %p, process: %p", + _ecore_exe_win32_job, pi.hProcess); + } + /* * Close pipe handles (do not continue to modify the parent). * We need to make sure that no handles to the write end of the