LIBC_CALL( ::close, (cerrpipe[1]) );
LIBC_CALL( ::setsid, () );
LIBC_CALL( ::sigprocmask, (SIG_SETMASK, &oldsig, 0) );
+
+ senf::Scheduler::instance().restart();
return;
}
LIBC_CALL( ::close, (coutpipe[1]) );
LIBC_CALL( ::close, (cerrpipe[1]) );
+ senf::Scheduler::instance().restart();
+
detail::DaemonWatcher watcher (pid, coutpipe[0], cerrpipe[0], stdout_, stderr_);
watcher.run();
int stdout, int stderr)
: childPid_(pid), coutpipe_(coutpipe), cerrpipe_(cerrpipe), stdout_(stdout),
stderr_(stderr), sigChld_(false),
+ cldSignal_ (SIGCHLD, senf::membind(&DaemonWatcher::sigChld, this)),
+ timer_ ("DaemanWatcher watchdog", senf::membind(&DaemonWatcher::childOk, this)),
coutForwarder_(coutpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 1)),
cerrForwarder_(cerrpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 2))
{
prefix_ void senf::detail::DaemonWatcher::run()
{
- Scheduler::instance().registerSignal(SIGCHLD, senf::membind(&DaemonWatcher::sigChld, this));
Scheduler::instance().process();
}
if (coutpipe_ == -1 && cerrpipe_ == -1) {
if (sigChld_)
childDied(); // does not return
- if (::kill(childPid_, SIGUSR1) < 0)
- if (errno != ESRCH) SENF_THROW_SYSTEM_EXCEPTION("::kill()");
- Scheduler::instance().timeout(
- Scheduler::instance().eventTime() + ClockService::seconds(1),
- senf::membind(&DaemonWatcher::childOk, this));
+ if (::kill(childPid_, SIGUSR1) < 0 && errno != ESRCH)
+ SENF_THROW_SYSTEM_EXCEPTION("::kill()");
+ timer_.timeout(Scheduler::instance().eventTime() + ClockService::seconds(1));
}
}
::signal(WTERMSIG(status),SIG_DFL);
::kill(::getpid(), WTERMSIG(status));
// should not be reached
- ::_exit(1);
+ ::_exit(126);
}
if (WEXITSTATUS(status) == 0)
- ::_exit(1);
+ ::_exit(127);
::_exit(WEXITSTATUS(status));
}
// senf::detail::DaemonWatcher::Forwarder
prefix_ senf::detail::DaemonWatcher::Forwarder::Forwarder(int src, Callback cb)
- : src_(src), cb_(cb)
-{
- Scheduler::instance().add(src_, senf::membind(&Forwarder::readData, this),
- Scheduler::EV_READ);
-}
+ : src_(src), cb_(cb),
+ readevent_("DaemanWatcher::Forwarder", senf::membind(&Forwarder::readData, this),
+ src_, scheduler::FdEvent::EV_READ)
+{}
prefix_ senf::detail::DaemonWatcher::Forwarder::~Forwarder()
{
- if (src_ != -1)
- Scheduler::instance().remove(src_);
-
- for (Targets::iterator i (targets_.begin()); i != targets_.end(); ++i)
- if (i->offset >= buffer_.size())
- Scheduler::instance().remove(i->fd);
+ targets_.clear_and_destroy(DestroyDelete());
}
prefix_ void senf::detail::DaemonWatcher::Forwarder::addTarget(int fd)
{
- Target target = { fd, 0 };
- targets_.push_back(target);
+ targets_.push_back(*(new Target(*this, fd)));
}
prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(int event)
while (1) {
n = ::read(src_,buf,1024);
if (n<0) {
- if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::read()");
- } else
+ if (errno != EINTR)
+ SENF_THROW_SYSTEM_EXCEPTION("::read()");
+ }
+ else
break;
}
if (n == 0) {
- // Hangup
- Scheduler::instance().remove(src_);
if (buffer_.empty())
cb_();
src_ = -1;
+ readevent_.disable();
return;
}
for (Targets::iterator i (targets_.begin()); i != targets_.end(); ++i)
if (i->offset >= buffer_.size())
- Scheduler::instance().add( i->fd,
- boost::bind(&Forwarder::writeData, this, _1, i),
- Scheduler::EV_WRITE );
+ i->writeevent.enable();
buffer_.insert(buffer_.end(), buf, buf+n);
}
-prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event,
- Targets::iterator target)
+prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event, Target * target)
{
if (event != Scheduler::EV_WRITE) {
// Broken pipe while writing data ? Not much, we can do here, we just drop the data
- Scheduler::instance().remove(target->fd);
- targets_.erase(target);
+ targets_.erase_and_destroy(Targets::current(*target),DestroyDelete());
if (targets_.empty() && src_ == -1)
cb_();
return;
i->offset -= n;
if (target->offset >= buffer_.size())
- Scheduler::instance().remove(target->fd);
+ target->writeevent.disable();
if (src_ == -1 && (buffer_.empty() || targets_.empty()))
cb_();
}