Go to the documentation of this file.
40 #include "blocxx/BLOCXX_config.h"
63 #include "blocxx/WinProcessUtils.hpp"
74 #ifdef BLOCXX_HAVE_UNISTD_H
78 #if defined(sigemptyset)
103 : m_status_available(pid > 0),
109 : m_status_available(static_cast<bool>(rep1)),
173 return !m_status_available;
178 return m_status_available && (WIFEXITED(
m_status) || WIFSIGNALED(
m_status));
183 return m_status_available && WIFEXITED(
m_status);
198 return m_status_available && WIFSIGNALED(
m_status);
208 return m_status_available && WIFSTOPPED(
m_status);
220 rep1 =
static_cast<int>(m_status_available);
226 return exitTerminated() && exitStatus() == 0;
239 else if (terminated())
241 if (exitTerminated())
243 return Format(
"exited with status %1",
String(exitStatus()));
245 else if (signalTerminated())
270 return ::kill(
pid,
sig) == 0 ? 0 : errno;
285 struct ZombieReaperPoolCreator
294 class ZombieReaper :
public Runnable
307 while (!status.terminated())
329 :
m_impl(new ChildProcessImpl())
353 :
m_impl(new ChildProcessImpl())
466 BLOCXX_THROW(ProcessErrorException,
"Process::m_pid == the current process id");
469 TimeoutTimer initialTimer(wait_initial);
470 TimeoutTimer closeTimer(wait_close);
471 TimeoutTimer termTimer(wait_term);
504 if (!killProcess(killTimeout, terminationSelectionFlag))
506 BLOCXX_THROW(ProcessErrorException,
"Child process has not terminated after killProcess().");
518 if (!
killWait(sigkillTimeout, SIGKILL,
"SIGKILL", terminationSelectionFlag))
520 BLOCXX_THROW(ProcessErrorException,
"Child process has not terminated after sending it a SIGKILL.");
532 float const mult = 1.20;
533 float const max_period = 5000.0;
534 float period = 100.0;
535 TimeoutTimer timer(wait_time);
539 period = (std::min)(max_period, period * mult);
554 DWORD rc1 = WaitForSingleObject(pid, 0);
555 if(rc1 == WAIT_FAILED)
562 BOOL rc = GetExitCodeProcess(pid, &exitCode);
576 bool Process::terminateByMessage(
const Timeout& waitTime)
578 DWORD bsmApp = BSM_APPLICATIONS;
580 BOOL bSucceed = BroadcastSystemMessage(BSF_IGNORECURRENTTASK, &bsmApp, termMsg, NULL, NULL);
599 bool Process::killProcess(
const Timeout& waitTime, ETerminationSelectionFlag terminationSelectionFlag)
601 DWORD result = ERROR_SUCCESS;
603 DWORD pId = WinUtils::getProcessIdNT(
m_pid);
606 result = WinUtils::killProcessGroup(pId);
610 result = WinUtils::killProcess(pId);
613 if (result != ERROR_SUCCESS)
632 return GetCurrentProcess();
645 wpid = ::waitpid(pid, &status, WNOHANG | WUNTRACED);
647 }
while (wpid < 0 && errno == EINTR);
653 return Process::Status(wpid, status);
660 bool Process::killWait(
const Timeout& wait_time,
int sig,
char const * signame, ETerminationSelectionFlag terminationSelectionFlag)
673 Format fmt(
"Failed sending %1 to process %2.", signame,
m_pid);
674 char const * msg = fmt.c_str();
This class can be used to store a global variable that is lazily initialized in a thread safe manner.
UnnamedPipeRef in() const
Stdin for the child process.
UnnamedPipeRef out() const
Stdout for the child process.
bool exitTerminated() const
IntrusiveReference< UnnamedPipe > UnnamedPipeRef
This class is the base of all exceptions thrown by BloCxx code.
UnnamedPipeRef err() const
Stderr for the child process.
This String class is an abstract data type that represents as NULL terminated string of characters.
BLOCXX_COMMON_API Process::Status waitPid(const ProcId &pid)
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
virtual int close()=0
Close the pipe.
void repr(int &rep1, int &rep2) const
BLOCXX_COMMON_API bool shouldUseWaitpidThreadFix()
#define BLOCXX_LAZY_GLOBAL_INIT(...)
Statically initialize a LazyGlobal instance.
static void sleep(UInt32 milliSeconds)
Suspend execution of the current thread until the given number of milliSeconds have elapsed.
void release()
Releases ownership of the ProcId and UnnamedPipes held by this object.
bool killWait(const Timeout &wait_time, int sig, char const *signame, ETerminationSelectionFlag terminationSelectionFlag)
virtual Process::Status pollStatus(ProcId pid)=0
ProcId pid() const
Process ID for the child process.
Process::Status pollStatusImpl(ProcId pid)
static Timeout relative(float seconds)
#define BLOCXX_DEFINE_EXCEPTION(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
class BLOCXX_COMMON_API Logger
const char * signalName(int sig)
LazyGlobal< String, char const *const > GlobalString
Process(UnnamedPipeRef const &in, UnnamedPipeRef const &out, UnnamedPipeRef const &err, ProcId pid)
#define BLOCXX_THROW_ERRNO_MSG(exType, msg)
Throw an exception using FILE, LINE, errno and strerror(errno)
ETerminationSelectionFlag
#define BLOCXX_GLOBAL_STRING_INIT(str)
String lastErrorMsg(bool socketError)
The ThreadPool class is used to coordinate a group of threads.
bool terminatedSuccessfully() const
int getPOSIXwaitpidStatus() const
Get the result from waitpid()
bool signalTerminated() const
There are two methods for creating a thread of execution in the blocxx systems.
virtual int kill(ProcId pid, int sig)=0
Sends signal sig to process pid.
static const char * TERM_MESSAGE
#define BLOCXX_LOG_DEBUG(logger, message)
Log message to logger with the Debug level.
void waitCloseTerm(const Timeout &wait_initial=Timeout::relative(5.0), const Timeout &wait_close=Timeout::relative(10.0), const Timeout &wait_term=Timeout::relative(15.0), ETerminationSelectionFlag terminationSelectionFlag=E_TERMINATE_PROCESS_GROUP)
Waits for the child process to terminate, taking increasingly severe measures to ensure that this hap...
#define BLOCXX_INVALID_HANDLE
virtual ~Process()
If release has been called on this object, does nothing.
String toString() const
Get a string representation of the status suitable for debugging or logging.
@ E_TERMINATE_PROCESS_GROUP
The process and any descendent processes which are in the process group will be terminated.
bool terminatesWithin(const Timeout &wait_time)
Abstract interface for abstracting details of dealing with a process.
float getRelative() const
ETimeoutType getType() const
GlobalString COMPONENT_NAME
IntrusiveReference< ProcessImpl > ProcessImplRef
A timeout can be absolute, which means that it will happen at the specified DateTime.