bool ActivePet::ownsProcess(HANDLE process) { BOOL result; if (!IsProcessInJob(process, m_job.get(), &result)) { printf("IsProcessInJob() failed: %d", GetLastError()); } return result ? true : false; }
/* FIXME */ g_val_t proc_run_func( void ) { DWORD aProcesses[MAXPROCESSES], cbNeeded, cProcesses; unsigned int i, running = 0; HANDLE hProcess; BOOL bResult; g_val_t val; if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) { cProcesses = 0; } else { cProcesses = cbNeeded / sizeof(DWORD); } #if (_WIN32_WINNT >= 0x0501) /* Only for XP or newer */ for (i = 0; i < cProcesses; i++) if (aProcesses[i] != 0) { hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, aProcesses[i]); if (hProcess != NULL) { if (IsProcessInJob(hProcess, NULL, &bResult)) { if (bResult) running++; } CloseHandle(hProcess); } } #endif val.uint32 = running; return val; }
void CPCD::Process::stop() { char filename[PATH_MAX*2+1]; BaseString::snprintf(filename, sizeof(filename), "%d", m_id); unlink(filename); if (is_bad_pid(m_pid)) { logger.critical("Stopping process with bogus pid: %d id: %d", m_pid, m_id); return; } m_status = STOPPING; #ifndef _WIN32 errno = 0; int signo= SIGTERM; if(m_shutdown_options == "SIGKILL") signo= SIGKILL; int ret = kill(-m_pid, signo); switch(ret) { case 0: logger.debug("Sent SIGTERM to pid %d", (int)-m_pid); break; default: logger.debug("kill pid: %d : %s", (int)-m_pid, strerror(errno)); break; } if(isRunning()){ errno = 0; ret = kill(-m_pid, SIGKILL); switch(ret) { case 0: logger.debug("Sent SIGKILL to pid %d", (int)-m_pid); break; default: logger.debug("kill pid: %d : %s\n", (int)-m_pid, strerror(errno)); break; } } #else if(isRunning()) { BOOL truth; HANDLE proc; require(proc = OpenProcess(PROCESS_QUERY_INFORMATION, 0, m_pid)); require(IsProcessInJob(proc, m_job, &truth)); require(truth == TRUE); require(CloseHandle(proc)); // Terminate process with exit code 37 require(TerminateJobObject(m_job, 37)); require(CloseHandle(m_job)); } #endif m_pid = bad_pid; m_status = STOPPED; }
int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { /* Check if we are not already associated with a job. * If this is the case, there is no way to switch to * another job. */ BOOL bInJob = FALSE; IsProcessInJob(GetCurrentProcess(), NULL, &bInJob); if (bInJob) { MessageBox( NULL, TEXT("Process already in a job"), TEXT(""), MB_ICONINFORMATION | MB_OK); return(-1); } /* Create the completion port that receives job notifications * Creates an input/output (I/O) completion port * and associates it with a specified file handle, * or creates an I/O completion port that is not * yet associated with a file handle, allowing association at a later time. * * Associating an instance of an opened file handle with an I/O completion * port allows a process to receive notification of the completion * of asynchronous I/O operations involving that file handle. * * FileHandle [in] * An open file handle or INVALID_HANDLE_VALUE. * The handle must be to an object that supports overlapped I/O. * If a handle is provided, it has to have been opened * for overlapped I/O completion. * For example, you must specify the FILE_FLAG_OVERLAPPED flag * when using the CreateFile function to obtain the handle. * * If INVALID_HANDLE_VALUE is specified, * the function creates an I/O completion port without associating it * with a file handle. In this case, the ExistingCompletionPort parameter * must be NULL and the CompletionKey parameter is ignored. * * ExistingCompletionPort [in, optional] * A handle to an existing I/O completion port or NULL. * If this parameter is NULL, the function creates a new I/O completion port and, * if the FileHandle parameter is valid, associates it with the new I/O completion port. * Otherwise no file handle association occurs. * The function returns the handle to the new I/O completion port if successful. * * */ g_hIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0); /* Create a thread that waits on the completion port */ g_hThreadIOCP = chBEGINTHREADEX( NULL, 0, JobNotify, NULL, 0, NULL); /* Create the job object */ g_job.Create(NULL, TEXT("JobLab")); g_job.SetEndOfJobInfo(JOB_OBJECT_POST_AT_END_OF_JOB); g_job.AssociateCompletionPort(g_hIOCP, COMPKEY_JOBOBJECT); DialogBox(hinstExe, MAKEINTRESOURCE(IDD_JOBLAB), NULL, Dlg_Proc); /* Post a special key that tells the completion port thread to terminate * Posts an I/O completion packet to an I/O completion port. * * CompletionPort [in] * A handle to an I/O completion port to which * the I/O completion packet is to be posted. * * dwNumberOfBytesTransferred [in] * The value to be returned through the lpNumberOfBytesTransferred * parameter of the GetQueuedCompletionStatus function. * * dwCompletionKey [in] * The value to be returned through the lpCompletionKey parameter * of the GetQueuedCompletionStatus function. * * lpOverlapped [in, optional] * The value to be returned through the lpOverlapped parameter * of the GetQueuedCompletionStatus function. * */ PostQueuedCompletionStatus(g_hIOCP, 0, COMPKEY_TERMINATE, NULL); /* Wait for the completion port thread to terminate */ WaitForSingleObject(g_hThreadIOCP, INFINITE); // Clean up everything properly CloseHandle(g_hIOCP); CloseHandle(g_hThreadIOCP); // NOTE: The job is closed when the g_job's destructor is called. return(0); }
HRESULT CNodeApplicationManager::Initialize(IHttpContext* context) { HRESULT hr; BOOL isInJob, createJob; JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo; if (this->initialized) { return S_OK; } ErrorIf(NULL == (this->eventProvider = new CNodeEventProvider()), ERROR_NOT_ENOUGH_MEMORY); CheckError(this->eventProvider->Initialize()); ErrorIf(NULL != this->asyncManager, ERROR_INVALID_OPERATION); ErrorIf(NULL == (this->asyncManager = new CAsyncManager()), ERROR_NOT_ENOUGH_MEMORY); CheckError(this->asyncManager->Initialize(context)); ErrorIf(NULL == (this->fileWatcher = new CFileWatcher()), ERROR_NOT_ENOUGH_MEMORY); CheckError(this->fileWatcher->Initialize(context)); // determine whether node processes should be created in a new job object // or whether current job object is adequate; the goal is to kill node processes when // the IIS worker process is killed while preserving current job limits, if any ErrorIf(!IsProcessInJob(GetCurrentProcess(), NULL, &isInJob), HRESULT_FROM_WIN32(GetLastError())); if (!isInJob) { createJob = TRUE; } else { ErrorIf(!QueryInformationJobObject(NULL, JobObjectExtendedLimitInformation, &jobInfo, sizeof jobInfo, NULL), HRESULT_FROM_WIN32(GetLastError())); if (jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK ) { createJob = TRUE; } else if(jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE ) { createJob = FALSE; } else if(jobInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK ) { createJob = TRUE; this->breakAwayFromJobObject = TRUE; } else { createJob = TRUE; } } if (createJob) { ErrorIf(NULL == (this->jobObject = CreateJobObject(NULL, NULL)), HRESULT_FROM_WIN32(GetLastError())); RtlZeroMemory(&jobInfo, sizeof jobInfo); jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; ErrorIf(!SetInformationJobObject(this->jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof jobInfo), HRESULT_FROM_WIN32(GetLastError())); } this->initialized = TRUE; this->GetEventProvider()->Log(L"iisnode initialized the application manager", WINEVENT_LEVEL_INFO); return S_OK; Error: this->GetEventProvider()->Log(L"iisnode failed to initialize the application manager", WINEVENT_LEVEL_ERROR); if (NULL != this->asyncManager) { delete this->asyncManager; this->asyncManager = NULL; } if (NULL != this->jobObject) { CloseHandle(this->jobObject); this->jobObject = NULL; } if (NULL != this->fileWatcher) { delete this->fileWatcher; this->fileWatcher = NULL; } return hr; }