/* This could be interesting to expose in public API */ static void _g_test_watcher_add_pid (GPid pid) { static gsize started = 0; HANDLE job; if (g_once_init_enter (&started)) { JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; job = CreateJobObjectW (NULL, NULL); memset (&info, 0, sizeof (info)); info.BasicLimitInformation.LimitFlags = 0x2000 /* JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE */; if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, sizeof (info))) g_warning ("Can't enable JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: %s", g_win32_error_message (GetLastError())); g_once_init_leave (&started,(gsize)job); } job = (HANDLE)started; if (!AssignProcessToJobObject(job, pid)) g_warning ("Can't assign process to job: %s", g_win32_error_message (GetLastError())); }
bool WindowsJob::create(bool useToExcuter, LPSECURITY_ATTRIBUTES lpJobAttributes) { if (jobHandle_) return false; useToExcuter_ = useToExcuter; jobHandle_ = CreateJobObjectW(lpJobAttributes, NULL); return NULL != jobHandle_; }
static void uv__init_global_job_handle(void) { /* Create a job object and set it up to kill all contained processes when * it's closed. Since this handle is made non-inheritable and we're not * giving it to anyone, we're the only process holding a reference to it. * That means that if this process exits it is closed and all the processes * it contains are killed. All processes created with uv_spawn that are not * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. * * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the * processes that we explicitly add are affected, and *their* subprocesses * are not. This ensures that our child processes are not limited in their * ability to use job control on Windows versions that don't deal with * nested jobs (prior to Windows 8 / Server 2012). It also lets our child * processes created detached processes without explicitly breaking away * from job control (which uv_spawn doesn't, either). */ SECURITY_ATTRIBUTES attr; JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; memset(&attr, 0, sizeof attr); attr.bInheritHandle = FALSE; memset(&info, 0, sizeof info); info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); if (uv_global_job_handle_ == NULL) uv_fatal_error(GetLastError(), "CreateJobObjectW"); if (!SetInformationJobObject(uv_global_job_handle_, JobObjectExtendedLimitInformation, &info, sizeof info)) uv_fatal_error(GetLastError(), "SetInformationJobObject"); }