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;
274 virtual Process::Status pollStatus(
ProcId pid)
285 struct ZombieReaperPoolCreator
287 static ThreadPool* create(
int dummy)
294 class ZombieReaper :
public Runnable
307 while (!status.terminated())
329 :
m_impl(new ChildProcessImpl())
353 :
m_impl(new ChildProcessImpl())
380 static_cast<ThreadPool>(g_zombieReaperPool).addWork(
new ZombieReaper(
m_pid,
m_impl));
390 static_cast<ThreadPool>(g_zombieReaperPool).addWork(
new ZombieReaper(
m_pid,
m_impl));
504 if (!killProcess(killTimeout, terminationSelectionFlag))
518 if (!
killWait(sigkillTimeout, SIGKILL,
"SIGKILL", terminationSelectionFlag))
532 float const mult = 1.20;
533 float const max_period = 5000.0;
534 float period = 100.0;
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);
571 return Process::Status(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);
673 Format fmt(
"Failed sending %1 to process %2.", signame,
m_pid);
674 char const * msg = fmt.
c_str();
#define BLOCXX_INVALID_HANDLE
bool terminatesWithin(const Timeout &wait_time)
A TimeoutTimer is used by an algorithm to determine when a timeout has expired.
void repr(int &rep1, int &rep2) const
void loop()
Meant to be called by timeout functions which loop, but don't want to reset the interval.
BLOCXX_COMMON_API Process::Status waitPid(const ProcId &pid)
UnnamedPipeRef in() const
Stdin for the child process.
This String class is an abstract data type that represents as NULL terminated string of characters.
const char * signalName(int sig)
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...
ProcId pid() const
Process ID for the child process.
int getPOSIXwaitpidStatus() const
Get the result from waitpid()
BLOCXX_COMMON_API bool shouldUseWaitpidThreadFix()
String lastErrorMsg(bool socketError)
void release()
Releases ownership of the ProcId and UnnamedPipes held by this object.
virtual int kill(ProcId pid, int sig)=0
Sends signal sig to process pid.
String toString() const
Get a string representation of the status suitable for debugging or logging.
Process(UnnamedPipeRef const &in, UnnamedPipeRef const &out, UnnamedPipeRef const &err, ProcId pid)
static Timeout relative(float seconds)
GlobalString COMPONENT_NAME
bool killWait(const Timeout &wait_time, int sig, char const *signame, ETerminationSelectionFlag terminationSelectionFlag)
UnnamedPipeRef err() const
Stderr for the child process.
virtual Process::Status pollStatus(ProcId pid)=0
virtual ~Process()
If release has been called on this object, does nothing.
A timeout can be absolute, which means that it will happen at the specified DateTime.
Timeout asAbsoluteTimeout() const
Converts the timer to an absolute timeout.
IntrusiveReference< ProcessImpl > ProcessImplRef
#define BLOCXX_GLOBAL_STRING_INIT(str)
virtual int close()=0
Close the pipe.
bool terminatedSuccessfully() const
The process and any descendent processes which are in the process group will be terminated.
class BLOCXX_COMMON_API Logger
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
Abstract interface for abstracting details of dealing with a process.
#define BLOCXX_DEFINE_EXCEPTION(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
bool exitTerminated() const
ETerminationSelectionFlag
This class can be used to store a global variable that is lazily initialized in a thread safe manner.
#define BLOCXX_LAZY_GLOBAL_INIT(...)
Statically initialize a LazyGlobal instance.
Process::Status pollStatusImpl(ProcId pid)
This class is the base of all exceptions thrown by BloCxx code.
#define BLOCXX_THROW_ERRNO_MSG(exType, msg)
Throw an exception using FILE, LINE, errno and strerror(errno)
UnnamedPipeRef out() const
Stdout for the child process.
float getRelative() const
bool signalTerminated() const
static void sleep(UInt32 milliSeconds)
Suspend execution of the current thread until the given number of milliSeconds have elapsed.
static const char * TERM_MESSAGE
#define BLOCXX_LOG_DEBUG(logger, message)
Log message to logger with the Debug level.
ETimeoutType getType() const
bool expired() const
Indicates whether the last loop time has exceeded the timeout.