|
Boost : |
From: Angus Leeming (angus.leeming_at_[hidden])
Date: 2004-06-23 03:46:55
Jonathan Biggar wrote:
> Angus Leeming wrote:
>> namespace {
>>
>> std::map<pid_t, int> completed_children;
>>
>> int status;
>> sig_atomic_t pid;
>>
>> }
>>
>> extern "C"
>> void child_handler(int)
>> {
>> pid = wait(&status);
>> std::map<pid_t, int>::iterator it =
>> completed_children.find(pid); if (it !=
>> completed_children.end())
>> it->second = status;
>> }
>>
>> I'm pretty sure that the above is safe code. It does the absolute
>> minimum in the handler routine. wait() is guaranteed to be async-safe.
>> Moreover, the handler receives only SIGCHLD signals and so cannot
>> receive multiple calls simultaneaously. However, I'm unsure whether it
>> Ok to search the map like this. Any advice?
>
> That's not safe code, since the child_handler() function could be called
> at any time, interrupting other code that is modifying the
> completed_children map.
Yes, I've thought of that. We just need to block any signals when we're
modifying the map:
unix_reaper::unix_reaper()
{
signal(SIGCHLD, boost_child_handler);
sigemptyset(&old_mask_);
sigemptyset(&new_mask_);
sigaddset(&new_mask_, SIGCHLD);
}
void unix_reaper::register(pid_t pid)
{
// Block the SIGCHLD signal.
sigprocmask(SIG_BLOCK, &new_mask_, &old_mask_);
// This is the map.
children_[pid] = -1;
// Unblock the SIGCHLD signal and restore the old mask.
sigprocmask(SIG_SETMASK, &old_mask_, 0);
}
Does this address your concern?
Angus
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk