41 #if defined(NCBI_OS_UNIX)
47 # include <sys/types.h>
48 # include <sys/time.h>
49 # include <sys/resource.h>
50 # include <sys/times.h>
51 # include <sys/wait.h>
52 # if defined(NCBI_OS_BSD) || defined(NCBI_OS_DARWIN)
53 # include <sys/sysctl.h>
55 # if defined(NCBI_OS_IRIX)
56 # include <sys/sysmp.h>
60 #elif defined(NCBI_OS_MSWIN)
65 # pragma warning (disable : 4191)
70 # include <mach/mach.h>
75 #define NCBI_USE_ERRCODE_X Corelib_Process
105 #define EXIT_INFO_CHECK \
106 if ( !IsPresent() ) { \
107 NCBI_THROW(CCoreException, eCore, \
108 "CProcess::CExitInfo state is unknown. " \
109 "Please check CExitInfo::IsPresent() first."); \
139 #if defined(NCBI_OS_UNIX)
140 return WIFEXITED(status) != 0;
141 #elif defined(NCBI_OS_MSWIN)
154 #if defined(NCBI_OS_UNIX)
155 return WIFSIGNALED(status) != 0;
156 #elif defined(NCBI_OS_MSWIN)
168 #if defined(NCBI_OS_UNIX)
169 return WEXITSTATUS(status);
170 #elif defined(NCBI_OS_MSWIN)
178 if ( !IsSignaled() ) {
181 #if defined(NCBI_OS_UNIX)
182 return WTERMSIG(status);
183 #elif defined(NCBI_OS_MSWIN)
195 #ifdef NCBI_THREAD_PID_WORKAROUND
196 # ifndef NCBI_OS_UNIX
197 # error "NCBI_THREAD_PID_WORKAROUND should only be defined on UNIX!"
199 TPid CCurrentProcess::sx_GetPid(EGetPidFlag flag)
201 if ( flag == ePID_GetThread ) {
207 static TPid s_CurrentPid = 0;
208 static TPid s_ParentPid = 0;
213 s_CurrentPid = getpid();
214 s_ParentPid = getppid();
222 TPid thr_pid = CThread::sx_GetThreadPid();
223 if (thr_pid && thr_pid != pid) {
226 CThread::sx_SetThreadPid(pid);
229 s_ParentPid = getppid();
232 return flag == ePID_GetCurrent ? s_CurrentPid : s_ParentPid;
239 #if defined(NCBI_OS_MSWIN)
240 return ::GetCurrentProcess();
241 #elif defined(NCBI_OS_UNIX)
249 #if defined(NCBI_OS_MSWIN)
250 return ::GetCurrentProcessId();
251 #elif defined NCBI_THREAD_PID_WORKAROUND
252 return sx_GetPid(ePID_GetCurrent);
253 #elif defined(NCBI_OS_UNIX)
261 #if defined(NCBI_OS_MSWIN)
262 PROCESSENTRY32 entry;
264 return entry.th32ParentProcessID;
269 #elif defined NCBI_THREAD_PID_WORKAROUND
270 return sx_GetPid(ePID_GetParent);
272 #elif defined(NCBI_OS_UNIX)
289 CErrnoKeeper() : m_Errno(errno) {}
290 int GetErrno()
const {
return m_Errno;}
291 ~CErrnoKeeper() {errno = m_Errno;}
299 CErrnoKeeper x_errno;
315 if (!(
flags & fFF_Exec) && use_async_safe) {
316 ERR_POST_X(3,
Warning <<
"It is not safe to call Fork() from a multithreaded program");
322 if (!(
flags & fFF_Exec)) {
327 if (use_async_safe) {
342 "CCurrentProcess::Fork() not implemented on this platform");
352 CSafeRedirect(
int fd,
bool* success_flag) :
353 m_OrigFD(fd), m_SuccessFlag(success_flag), m_Redirected(
false)
355 if ((m_DupFD = ::fcntl(fd, F_DUPFD, STDERR_FILENO + 1)) < 0) {
357 "Error duplicating file descriptor #" << fd <<
361 void Redirect(
int new_fd)
363 if (new_fd != m_OrigFD) {
364 int error = ::dup2(new_fd, m_OrigFD);
366 CErrnoKeeper x_errno;
369 "Error redirecting file descriptor #" << m_OrigFD <<
378 CErrnoKeeper x_errno;
379 if (m_Redirected && !*m_SuccessFlag) {
381 ::dup2(m_DupFD, m_OrigFD);
399 "Prohibited, there are already child threads running: " <<
n);
402 bool success_flag =
false;
404 CSafeRedirect stdin_redirector (
STDIN_FILENO, &success_flag);
405 CSafeRedirect stdout_redirector(
STDOUT_FILENO, &success_flag);
406 CSafeRedirect stderr_redirector(STDERR_FILENO, &success_flag);
411 if ((new_fd = ::open(
"/dev/null", O_RDONLY)) < 0) {
415 stdin_redirector.Redirect(new_fd);
418 if ((new_fd = ::open(
"/dev/null", O_WRONLY)) < 0) {
424 stdout_redirector.Redirect(new_fd);
428 if ((new_fd = ::open(
"/dev/null", O_WRONLY | O_APPEND)) < 0) {
433 if ((new_fd = ::open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0666)) < 0) {
435 "Unable to open logfile \"" << logfile <<
"\": " <<
s_ErrnoToString());
440 stderr_redirector.Redirect(new_fd);
466 ERR_POST_X(2,
"[Daemonize] Failed to immune from "
467 "TTY accruals: " << e <<
" ... continuing anyways");
471 if (::chdir(
"/") ) { };
495 CErrnoKeeper x_errno;
498 catch (exception& e) {
499 CErrnoKeeper x_errno;
504 "CCurrentProcess::Daemonize() not implemented on this platform");
526 : m_Process(process),
558 hProcess = ::OpenProcess(desired_access,
FALSE,
GetPid());
561 *errcode = ::GetLastError();
574 ::CloseHandle(handle);
594 bool current =
false;
598 #if defined(NCBI_OS_MSWIN)
611 #if defined(NCBI_OS_UNIX)
612 return kill(
GetPid(), 0) == 0 || errno == EPERM;
614 #elif defined(NCBI_OS_MSWIN)
618 return status == ERROR_ACCESS_DENIED;
621 ::GetExitCodeProcess(hProcess, &status);
623 return status == STILL_ACTIVE;
630 #if defined(NCBI_OS_UNIX)
635 if (kill(pid, SIGTERM) < 0 && errno == EPERM) {
641 unsigned long x_timeout = timeout;
643 TPid reap = waitpid(pid, 0, WNOHANG);
645 if (reap != (
TPid)(-1)) {
649 if (errno != ECHILD) {
653 if (kill(pid, 0) < 0)
657 if (x_sleep > x_timeout) {
664 x_timeout -= x_sleep;
669 int res = kill(pid, SIGKILL);
675 waitpid(pid, 0, WNOHANG);
679 return kill(pid, 0) < 0;
681 #elif defined(NCBI_OS_MSWIN)
684 bool safe = (timeout > 0);
696 bool allow_wait =
true;
700 hProcess =
x_GetHandle(PROCESS_CREATE_THREAD | PROCESS_TERMINATE | SYNCHRONIZE);
711 if (err != ERROR_ACCESS_DENIED) {
726 if (!::OpenThreadToken(::GetCurrentThread(),
727 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
FALSE, &hToken)) {
728 err = ::GetLastError();
729 if (err != ERROR_NO_TOKEN) {
734 if (!::OpenProcessToken(::GetCurrentProcess(),
735 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) {
743 TOKEN_PRIVILEGES tp, tp_prev;
744 DWORD tp_prev_size =
sizeof(tp_prev);
746 tp.PrivilegeCount = 1;
747 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
748 ::LookupPrivilegeValue(
NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
750 if (!::AdjustTokenPrivileges(hToken,
FALSE, &tp,
sizeof(tp), &tp_prev, &tp_prev_size)) {
752 ::CloseHandle(hToken);
757 err = ::GetLastError();
758 if (err == ERROR_NOT_ALL_ASSIGNED) {
763 ::CloseHandle(hToken);
768 hProcess = ::OpenProcess(PROCESS_TERMINATE,
FALSE,
GetPid());
771 ::AdjustTokenPrivileges(hToken,
FALSE, &tp_prev,
sizeof(tp_prev),
NULL,
NULL);
772 ::CloseHandle(hToken);
781 bool terminated =
false;
788 if ( safe && allow_wait ) {
791 FARPROC exitproc = ::GetProcAddress(::GetModuleHandleA(
"KERNEL32.DLL"),
"ExitProcess");
793 hThread = ::CreateRemoteThread(hProcess,
NULL, 0, (LPTHREAD_START_ROUTINE)exitproc, 0, 0, 0);
796 (::WaitForSingleObject(hProcess, timeout) == WAIT_OBJECT_0)){
803 if ( ::TerminateProcess(hProcess, -1) != 0 ) {
804 DWORD err = ::GetLastError();
805 if (err == ERROR_INVALID_HANDLE) {
818 if (safe && terminated) {
824 unsigned long linger_timeout = (elapsed < timeout) ?
825 (
unsigned long)((double)timeout - elapsed) : 0;
833 if (x_sleep > linger_timeout) {
834 x_sleep = linger_timeout;
840 linger_timeout -= x_sleep;
845 ::CloseHandle(hThread);
866 HANDLE const snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
870 PROCESSENTRY32 entry;
871 entry.dwSize =
sizeof(PROCESSENTRY32);
874 if (!::Process32First(snapshot, &entry)) {
875 ::CloseHandle(snapshot);
879 if (entry.th32ParentProcessID == pid) {
883 timeout = (elapsed < timeout) ? (
unsigned long)((double)timeout - elapsed) : 0;
885 ::CloseHandle(snapshot);
891 ::CloseHandle(snapshot);
896 while (::Process32Next(snapshot, &entry));
903 timeout = (elapsed < timeout) ? (
unsigned long)((double)timeout - elapsed) : 0;
905 ::CloseHandle(snapshot);
912 ::CloseHandle(snapshot);
921 #if defined(NCBI_OS_UNIX)
924 if (pgid == (
TPid)(-1)) {
927 return errno == ESRCH;
931 #elif defined(NCBI_OS_MSWIN)
938 unsigned long x_timeout = timeout;
953 #if defined(NCBI_OS_UNIX)
956 if (kill(-pgid, SIGTERM) < 0 && errno == EPERM) {
962 unsigned long x_timeout = timeout;
965 TPid reap = waitpid(pgid, 0, WNOHANG);
967 if (reap != (
TPid)(-1)) {
971 if (errno != ECHILD) {
975 if (kill(-pgid, 0) < 0) {
980 if (x_sleep > x_timeout) {
987 x_timeout -= x_sleep;
992 int res = kill(-pgid, SIGKILL);
998 waitpid(pgid, 0, WNOHANG);
1001 return kill(-pgid, 0) < 0;
1023 #if defined(NCBI_OS_UNIX)
1030 TPid ws = waitpid(pid, &status, options);
1036 info->status = status;
1038 return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
1039 }
else if (ws == 0) {
1049 if (x_sleep > timeout) {
1054 }
else if (errno != EINTR) {
1062 #elif defined(NCBI_OS_MSWIN)
1064 bool allow_wait =
true;
1080 if (::GetExitCodeProcess(hProcess, &x_status)) {
1081 if (x_status == STILL_ACTIVE) {
1082 if (allow_wait && timeout) {
1084 ? INFINITE : (
DWORD) timeout);
1085 DWORD ws = ::WaitForSingleObject(hProcess, tv);
1089 _ASSERT(x_status == STILL_ACTIVE);
1092 if (::GetExitCodeProcess(hProcess, &x_status)) {
1093 if (x_status != STILL_ACTIVE) {
1116 if (
info && x_status == STILL_ACTIVE) {
1122 info->status = x_status;
1134 #if defined(NCBI_OS_MSWIN)
1138 FILETIME ft_creation, ft_exit, ft_kernel, ft_user;
1142 res = ::GetProcessTimes(handle, &ft_creation, &ft_exit, &ft_kernel, &ft_user);
1145 res = ::GetThreadTimes(handle, &ft_creation, &ft_exit, &ft_kernel, &ft_user);
1157 ::GetSystemTimeAsFileTime(&ft_sys);
1161 i.LowPart = ft_creation.dwLowDateTime;
1162 i.HighPart = ft_creation.dwHighDateTime;
1164 i.LowPart = ft_sys.dwLowDateTime;
1165 i.HighPart = ft_sys.dwHighDateTime;
1168 i.QuadPart = v_diff;
1169 *real = (
i.LowPart + ((
Uint8)
i.HighPart << 32)) * 1.0e-7;
1172 *sys = (ft_kernel.dwLowDateTime + ((
Uint8) ft_kernel.dwHighDateTime << 32)) * 1e-7;
1175 *user = (ft_user.dwLowDateTime + ((
Uint8) ft_user.dwHighDateTime << 32)) * 1e-7;
1182 #if defined(NCBI_OS_LINUX)
1183 bool s_Linux_GetTimes_ProcStat(
TPid pid,
double* real,
double* user,
double* sys,
CProcess::EWhat what)
1195 CLinuxFeature::CProcStat ps(pid);
1199 int fu = 14, fs = 15;
1209 if (start > 0 && uptime > 0) {
1210 *real = uptime - (double)start / (
double)tick;
1244 #if defined(NCBI_OS_MSWIN)
1261 #elif defined(NCBI_OS_UNIX)
1263 # if defined(NCBI_OS_LINUX)
1264 return s_Linux_GetTimes_ProcStat(
GetPid(), real, user, sys, what);
1283 #if defined(NCBI_OS_MSWIN)
1299 #elif defined(NCBI_OS_UNIX)
1304 # if defined(NCBI_OS_LINUX)
1308 if ( s_Linux_GetTimes_ProcStat(0 , real, user, sys, what) ) {
1313 # if defined(HAVE_GETRUSAGE)
1314 int who = RUSAGE_SELF;
1320 who = RUSAGE_CHILDREN;
1323 #ifdef RUSAGE_THREAD
1324 who = RUSAGE_THREAD;
1334 memset(&ru,
'\0',
sizeof(ru));
1335 if (getrusage(who, &ru) != 0) {
1340 *user = double(ru.ru_utime.tv_sec) + double(ru.ru_utime.tv_usec) / 1e6;
1343 *sys = double(ru.ru_stime.tv_sec) + double(ru.ru_stime.tv_usec) / 1e6;
1355 clock_t
t = times(&
buf);
1356 if (
t == (clock_t)(-1) ) {
1366 *user = (double)
buf.tms_utime / (
double)tick;
1369 *sys = (double)
buf.tms_stime / (
double)tick;
1381 #if defined(NCBI_OS_MSWIN)
1403 BOOL (STDMETHODCALLTYPE
FAR * dllGetProcessMemoryInfo)
1405 dllGetProcessMemoryInfo = psapi_dll.
GetEntryPoint_Func(
"GetProcessMemoryInfo", &dllGetProcessMemoryInfo);
1406 if (dllGetProcessMemoryInfo) {
1407 if ( !dllGetProcessMemoryInfo(handle, memcounters,
sizeof(memcounters)) ) {
1454 #if defined(NCBI_OS_MSWIN)
1464 #elif defined(NCBI_OS_LINUX)
1478 #if defined(NCBI_OS_MSWIN)
1481 #elif defined(NCBI_OS_LINUX)
1486 #elif defined(NCBI_OS_SOLARIS)
1495 #elif defined(HAVE_GETRUSAGE)
1514 #if defined(NCBI_OS_LINUX_)
1524 memset(&ru,
'\0',
sizeof(ru));
1525 if (getrusage(RUSAGE_SELF, &ru) == 0) {
1527 #if defined(NCBI_OS_DARWIN)
1529 usage.total_peak = ru.ru_maxrss;
1530 usage.resident_peak = ru.ru_maxrss;
1533 usage.resident_peak = ru.ru_maxrss * 1024;
1534 usage.total_peak = ru.ru_maxrss * 1024;
1536 #if !defined(NCBI_OS_DARWIN)
1544 #define KBT(v) ((v) * 1024 / ticks)
1545 usage.total = KBT(ru.ru_ixrss + ru.ru_idrss + ru.ru_isrss);
1546 if (
usage.total > 0) {
1548 usage.total_peak = KBT(ru.ru_ixrss + ru.ru_isrss) + maxrss;
1549 usage.resident = KBT(ru.ru_idrss);
1550 usage.resident_peak = maxrss;
1551 usage.shared = KBT(ru.ru_ixrss);
1552 usage.data = KBT(ru.ru_idrss);
1553 usage.stack = KBT(ru.ru_isrss);
1556 usage.total_peak = maxrss;
1557 usage.resident_peak = maxrss;
1560 #if defined(NCBI_OS_DARWIN)
1561 if (
usage.total > 0) {
1570 #if defined(NCBI_OS_DARWIN)
1572 #ifdef MACH_TASK_BASIC_INFO
1573 task_flavor_t flavor = MACH_TASK_BASIC_INFO;
1574 struct mach_task_basic_info t_info;
1575 mach_msg_type_number_t t_info_count = MACH_TASK_BASIC_INFO_COUNT;
1577 task_flavor_t flavor = TASK_BASIC_INFO;
1578 struct task_basic_info t_info;
1579 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
1581 if (task_info(mach_task_self(), flavor, (task_info_t)&t_info, &t_info_count) == KERN_SUCCESS) {
1582 usage.total = t_info.resident_size;
1583 usage.resident = t_info.resident_size;
1607 #if defined(NCBI_OS_MSWIN)
1608 PROCESSENTRY32 entry;
1610 return entry.cntThreads;
1614 #elif defined(NCBI_OS_LINUX)
1615 return CLinuxFeature::GetThreadCount(
GetPid());
1626 #if defined(NCBI_OS_MSWIN)
1627 PROCESSENTRY32 entry;
1629 return entry.cntThreads;
1633 #elif defined(NCBI_OS_LINUX)
1634 return CLinuxFeature::GetThreadCount();
1650 #if defined(NCBI_OS_LINUX)
1651 return CLinuxFeature::GetFileDescriptorsCount(
GetPid());
1661 #if defined(NCBI_OS_UNIX)
1666 rlim_t cur_limit = -1;
1667 rlim_t max_limit = -1;
1668 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
1669 cur_limit = rlim.rlim_cur;
1670 max_limit = rlim.rlim_max;
1673 cur_limit =
static_cast<rlim_t
>(sysconf(_SC_OPEN_MAX));
1676 *soft_limit = (cur_limit > INT_MAX) ? INT_MAX :
static_cast<int>(cur_limit);
1679 *hard_limit = (max_limit > INT_MAX) ? INT_MAX :
static_cast<int>(max_limit);
1682 #if defined(NCBI_OS_LINUX)
1683 n = CLinuxFeature::GetFileDescriptorsCount(
GetPid());
1686 if (n < 0 && cur_limit > 0) {
1687 int max_fd = (cur_limit > INT_MAX) ? INT_MAX :
static_cast<int>(cur_limit);
1688 for (
int fd = 0; fd < max_fd; ++fd) {
1689 if (fcntl(fd, F_GETFD, 0) == -1) {
1690 if (errno == EBADF) {
1703 if ( soft_limit ) { *soft_limit = -1; }
1704 if ( hard_limit ) { *hard_limit = -1; }
1743 if (real_dir.empty()) {
1778 unsigned int ref = 0;
1784 if (
m_PID != pid ) {
1796 out << pid << endl << ref << endl;
1798 if ( !
out.good() ) {
1800 "Unable to write into PID file " +
m_Path +
": "
1854 bool valid_file =
true;
1855 unsigned int ref = 1;
1871 in >> old_pid >> ref;
1872 if ( old_pid == pid ) {
1878 "Process is still running", old_pid);
1889 out << pid << endl << ref << endl;
1891 if ( !
out.good() ) {
1893 "Unable to write into PID file " +
m_Path +
": "
1903 switch (GetErrCode()) {
1905 case eWrite:
return "eWrite";
void Release()
Manually force the resource to be released.
Extended exit information for waited process.
static clock_t GetClockTicksPerSecond(void)
Get number of (statistics) clock ticks per second.
static double GetUptime(void)
Get system uptime in seconds.
static bool FindProcessEntry(DWORD id, PROCESSENTRY32 &entry)
Find process entry information by process identifier (pid).
std::ofstream out("events_result.xml")
main entry point for tests
@ eTriState_False
The value is equivalent to false/no.
@ eTriState_True
The value is equivalent to true/yes.
@ eTriState_Unknown
The value is indeterminate.
CDiagContext & GetDiagContext(void)
Get diag context instance.
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
static void UpdateOnFork(TOnForkFlags flags)
Update diagnostics after fork().
void PrintStop(void)
Print exit message.
@ fOnFork_ResetTimer
Reset execution timer.
@ fOnFork_AsyncSafe
After a fork() in a multithreaded program, the child can safely call only async-signal-safe functions...
@ fOnFork_PrintStart
Log app-start.
TFunc GetEntryPoint_Func(const string &name, TFunc *func)
Get DLLs entry point (function).
static void SetFromWindowsError(void)
Set last error on MS Windows using GetLastError()
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
static void SetFromErrno(void)
Set last error using current "errno" code.
void Warning(CExceptionArgs_Base &args)
static void Set(ECode code)
Set last error using native error code enum.
#define NCBI_THROW2(exception_class, err_code, message, extra)
Throw exception with extra parameter.
#define NCBI_THROW_FMT(exception_class, err_code, message)
The same as NCBI_THROW but with message processed as output to ostream.
static void SetWindowsError(int native_err_code)
Set last error using Windows-specific error code.
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
static string GetTmpDir(void)
Get temporary directory.
Int8 GetLength(void) const
Get size of file.
virtual bool Remove(TRemoveFlags flags=eRecursive) const
Remove a directory entry.
static string MakePath(const string &dir=kEmptyStr, const string &base=kEmptyStr, const string &ext=kEmptyStr)
Assemble a path from basic components.
static void SplitPath(const string &path, string *dir=0, string *base=0, string *ext=0)
Split a path string into its basic components.
int64_t Int8
8-byte (64-bit) signed integer
uint64_t Uint8
8-byte (64-bit) unsigned integer
virtual const char * GetErrCodeString(void) const override
bool GetTimes(double *real, double *user, double *sys, EWhat what=eProcess)
Get process execution times.
static int GetThreadCount(void)
Get the number of threads in the current process.
TPid x_GetPid(void) const
~CPIDGuard(void)
Destructor.
CPIDGuard(const string &filename)
Create/check PID file.
TProcessHandle x_GetHandle(DWORD desired_access, DWORD *errcode=0) const
static TPid GetParentPid(void)
Get process identifier (pid) for the parent of the current process.
bool IsPresent(void) const
TRUE if the object contains information about the process state.
EType
How to interpret the used process identifier.
TProcessHandle GetHandle(void) const
Get stored process handle.
static bool KillGroupById(TPid pgid, unsigned long timeout=kDefaultKillTimeout)
Terminate a group of processes with specified ID.
bool KillGroup(unsigned long timeout=kDefaultKillTimeout) const
Terminate a group of processes.
static TPid GetPid(void)
Get process identifier (pid) for the current process.
int status
Process status information.
unsigned int TDaemonFlags
Bit-wise OR of FDaemonFlags.
static int GetFileDescriptorsCount(int *soft_limit=NULL, int *hard_limit=NULL)
Get the number of file descriptors consumed by the current process, and optional system wide file des...
EType m_Type
Type of process identifier.
EWhat
Process information "target".
unique_ptr< CInterProcessLock > m_MTGuard
bool IsExited(void) const
TRUE if the process terminated normally.
bool GetMemoryUsage(SMemoryUsage &usage)
Get process memory usage.
int GetSignal(void) const
Get the signal number that has caused the process to terminate (UNIX only).
bool Kill(unsigned long timeout=kDefaultKillTimeout)
Terminate process.
static bool GetMemoryUsage(SMemoryUsage &usage)
Get current process memory usage.
ETriState m_IsCurrent
Status that m_Process represent the current process.
static TPid Daemonize(const char *logfile=0, TDaemonFlags flags=0)
Go daemon.
static TPid Fork(TForkFlags flags=fFF_UpdateDiag)
Fork the process.
unique_ptr< CInterProcessLock > m_PIDGuard
static const unsigned long kInfiniteTimeoutMs
Infinite timeout (milliseconds).
CExitInfo(void)
Constructor.
intptr_t m_Process
Process identifier.
bool IsCurrent(void)
Checks that stored process identifier (pid) represent the current process.
int Wait(unsigned long timeout=kInfiniteTimeoutMs, CExitInfo *info=0) const
Wait until process terminates.
void x_CloseHandle(TProcessHandle handle) const
int GetThreadCount(void)
Get the number of threads in the process.
static const unsigned long kDefaultKillTimeout
Default wait time (milliseconds) between "soft" and "hard" attempts to terminate a process.
unsigned TForkFlags
Bit-wise OR of FForkFlags.
pid_t TPid
Process identifier (PID) and process handle.
bool IsAlive(void) const
TRUE if the process is still alive.
void Release(void)
Release PID.
bool IsSignaled(void) const
TRUE if the process terminated by a signal (UNIX only).
CProcess(void)
Default constructor. Uses the current process pid.
TPid GetPid(void) const
Get stored process identifier (pid).
static bool GetTimes(double *real, double *user, double *sys, EWhat what=eProcess)
Get current process execution times.
bool IsAlive(void) const
Check for process existence.
static TProcessHandle GetHandle(void)
Get process handle for the current process (esp.
int GetFileDescriptorsCount(void)
Get the number of file descriptors consumed by the current process.
EType GetType(void) const
Get type of stored process identifier.
void UpdatePID(TPid pid=0)
Update PID in the file.
void Remove(void)
Remove the file.
int GetExitCode(void) const
Get process exit code.
@ ePid
A real process identifier (pid).
@ eHandle
A process handle (MS Windows).
@ eWrite
Unable to write into the PID file.
@ eStillRunning
The process listed in the file is still around.
@ eChildren
All children of the calling process.
@ eProcess
Current process.
@ fFF_UpdateDiag
Reset diagnostics timer and log an app-start message in the child process.
@ fFF_AllowExceptions
Throw an exception on error.
@ fDF_KeepCWD
Don't change CWD to "/".
@ fDF_KeepParent
Do not exit the parent process but return.
@ fDF_KeepStdout
Keep stdout open as "/dev/null" (WO)
@ fDF_AllowExceptions
Throw an exception in case of an error.
@ fDF_KeepStdin
Keep stdin open as "/dev/null" (RO)
@ fDF_AllowThreads
Do not fail if pre-existing threads are detected.
@ fDF_ImmuneTTY
Make daemon immune to re-acquiring a controlling terminal.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
static Uint8 StringToUInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Uint8.
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
@ fConvErr_NoThrow
Do not throw an exception on error.
static unsigned int GetThreadsCount()
Get total amount of threads This amount does not contain main thread.
#define DEFINE_STATIC_FAST_MUTEX(id)
Define static fast mutex and initialize it.
double Elapsed(void) const
Return time elapsed since first Start() or last Restart() call (in seconds).
const long kMilliSecondsPerSecond
Number milliseconds in one second.
void Start(void)
Start the timer.
#define INVALID_HANDLE_VALUE
A value for an invalid file handle.
#define HANDLE
An abstraction for a file handle.
Definition of all error codes used in corelib (xncbi.lib).
const struct ncbi::grid::netcache::search::fields::SIZE size
Defines MS Windows specific private functions and classes.
Private UNIX specific features.
bool s_Win_GetMemoryUsage(HANDLE handle, CProcess::SMemoryUsage &usage)
TPid s_Daemonize(const char *logfile, CCurrentProcess::TDaemonFlags flags)
bool s_Win_GetHandleTimes(HANDLE handle, double *real, double *user, double *sys, CProcess::EWhat what)
static bool s_Win_KillGroup(DWORD pid, CStopWatch *timer, unsigned long &timeout)
bool s_Win_GetMemoryCounters(HANDLE handle, SProcessMemoryCounters &memcounters)
const unsigned long kWaitPrecisionMs
static string s_ErrnoToString()
Defines process management classes.
Static variables safety - create on demand, destroy on application termination.
void SleepMilliSec(unsigned long ml_sec, EInterruptOnSignal onsignal=eRestartOnSignal)
bool GetMemoryUsage(size_t *total, size_t *resident, size_t *shared)
Defines NCBI C++ diagnostic APIs, classes, and macros.
Define class Dll and for Portable DLL handling.
Defines NCBI C++ Toolkit portable error codes.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Multi-threading – classes, functions, and features.
Defines: CTimeFormat - storage class for time format.
std::istream & in(std::istream &in_, double &x_)
double f(double x_, const double &y_)
static const TModelUnit kUndefined
Process memory usage information, in bytes.
SIZE_T QuotaPagedPoolUsage
SIZE_T QuotaNonPagedPoolUsage
SIZE_T QuotaPeakNonPagedPoolUsage
SIZE_T PeakWorkingSetSize
SIZE_T QuotaPeakPagedPoolUsage