in demo_example/asio/asio/detail/impl/signal_set_service.ipp [308:380]
asio::error_code signal_set_service::add(
signal_set_service::implementation_type& impl,
int signal_number, asio::error_code& ec)
{
// Check that the signal number is valid.
if (signal_number < 0 || signal_number >= max_signal_number)
{
ec = asio::error::invalid_argument;
return ec;
}
signal_state* state = get_signal_state();
static_mutex::scoped_lock lock(state->mutex_);
// Find the appropriate place to insert the registration.
registration** insertion_point = &impl.signals_;
registration* next = impl.signals_;
while (next && next->signal_number_ < signal_number)
{
insertion_point = &next->next_in_set_;
next = next->next_in_set_;
}
// Only do something if the signal is not already registered.
if (next == 0 || next->signal_number_ != signal_number)
{
registration* new_registration = new registration;
#if defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION)
// Register for the signal if we're the first.
if (state->registration_count_[signal_number] == 0)
{
# if defined(ASIO_HAS_SIGACTION)
using namespace std; // For memset.
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = asio_signal_handler;
sigfillset(&sa.sa_mask);
if (::sigaction(signal_number, &sa, 0) == -1)
# else // defined(ASIO_HAS_SIGACTION)
if (::signal(signal_number, asio_signal_handler) == SIG_ERR)
# endif // defined(ASIO_HAS_SIGACTION)
{
# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
ec = asio::error::invalid_argument;
# else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
ec = asio::error_code(errno,
asio::error::get_system_category());
# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
delete new_registration;
return ec;
}
}
#endif // defined(ASIO_HAS_SIGNAL) || defined(ASIO_HAS_SIGACTION)
// Record the new registration in the set.
new_registration->signal_number_ = signal_number;
new_registration->queue_ = &impl.queue_;
new_registration->next_in_set_ = next;
*insertion_point = new_registration;
// Insert registration into the registration table.
new_registration->next_in_table_ = registrations_[signal_number];
if (registrations_[signal_number])
registrations_[signal_number]->prev_in_table_ = new_registration;
registrations_[signal_number] = new_registration;
++state->registration_count_[signal_number];
}
ec = asio::error_code();
return ec;
}