seconds takes 6.
Tom:
-- Signal handling
+- Thread shutdown
- Make the log level configurable.
-- Unique identifier
- Incrementing sequence number (The sequence number is always 1)
- In boost-net-dns/network_array.hpp fix the type-punning to enforce better type
+++ /dev/null
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+++ /dev/null
-//
-// Copyright (c) 2009, 2010 Boris Schaeling <boris@highscore.de>
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_ASIO_POSIX_BASIC_SIGNAL_HANDLER_HPP
-#define BOOST_ASIO_POSIX_BASIC_SIGNAL_HANDLER_HPP
-
-#include <boost/asio.hpp>
-#include <signal.h>
-
-namespace boost {
-namespace asio {
-namespace posix {
-
-template <typename Service>
-class basic_signal_handler
- : public boost::asio::basic_io_object<Service>
-{
-public:
- explicit basic_signal_handler(boost::asio::io_service &io_service)
- : boost::asio::basic_io_object<Service>(io_service)
- {
- }
-
- void add_signal(int signal, int flags = 0, sigset_t *mask = 0)
- {
- this->service.add_signal(this->implementation, signal, flags, mask);
- }
-
- void remove_signal(int signal)
- {
- this->service.remove_signal(this->implementation, signal);
- }
-
- int wait()
- {
- boost::system::error_code ec;
- int signal = this->service.wait(this->implementation, ec);
- boost::asio::detail::throw_error(ec);
- return signal;
- }
-
- int wait(boost::system::error_code &ec)
- {
- return this->service.wait(this->implementation, ec);
- }
-
- template <typename Handler>
- void async_wait(Handler handler)
- {
- this->service.async_wait(this->implementation, handler);
- }
-};
-
-}
-}
-}
-
-#endif
+++ /dev/null
-//
-// Copyright (c) 2009, 2010 Boris Schaeling <boris@highscore.de>
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_ASIO_POSIX_BASIC_SIGNAL_HANDLER_SERVICE_HPP
-#define BOOST_ASIO_POSIX_BASIC_SIGNAL_HANDLER_SERVICE_HPP
-
-#include "signal_handler_impl.hpp"
-#include <boost/asio.hpp>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/system/system_error.hpp>
-#include <cstring>
-#include <signal.h>
-#include <unistd.h>
-
-namespace boost {
-namespace asio {
-namespace posix {
-
-template <typename SignalHandlerImplementation = signal_handler_impl>
-class basic_signal_handler_service
- : public boost::asio::io_service::service
-{
-public:
- static boost::asio::io_service::id id;
-
- explicit basic_signal_handler_service(boost::asio::io_service &io_service)
- : boost::asio::io_service::service(io_service),
- async_wait_work_(new boost::asio::io_service::work(async_wait_io_service_)),
- async_wait_thread_(boost::bind(&boost::asio::io_service::run, &async_wait_io_service_))
- {
- }
-
- virtual ~basic_signal_handler_service()
- {
- // The async_wait thread will finish when async_wait_work_ is reset as all asynchronous
- // operations have been aborted and were discarded before (in destroy).
- async_wait_work_.reset();
-
- // Event processing is stopped to discard queued operations.
- async_wait_io_service_.stop();
-
- // The async_wait thread is joined to make sure the signal handler service is
- // destroyed _after_ the thread is finished (not that the thread tries to access
- // instance properties which don't exist anymore).
- async_wait_thread_.join();
- }
-
- typedef boost::shared_ptr<SignalHandlerImplementation> implementation_type;
-
- void construct(implementation_type &impl)
- {
- // We must count the I/O objects and can't rely on the shared pointer impl_
- // as an asynchronous call can hold a shared pointer at any time, too, thus
- // preventing the implementation to be destroyed in destroy().
- ++count_;
-
- implementation_type shared_impl = impl_.lock();
- if (shared_impl)
- {
- impl = shared_impl;
- }
- else
- {
- impl.reset(new SignalHandlerImplementation());
- impl_ = impl;
- fd_ = impl->write_end();
- }
- }
-
- void destroy(implementation_type &impl)
- {
- // If an asynchronous call is currently waiting for a signal
- // we must interrupt the blocked call to make sure it returns.
- if (!--count_)
- impl->destroy();
-
- impl.reset();
- }
-
- void add_signal(implementation_type &impl, int signal, int flags, sigset_t *mask)
- {
- struct sigaction act, oldact;
-
- std::memset(&act, 0, sizeof(struct sigaction));
- act.sa_handler = basic_signal_handler_service<SignalHandlerImplementation>::signal_handler;
- act.sa_flags = flags;
- if (mask)
- act.sa_mask = *mask;
-
- int res = sigaction(signal, &act, &oldact);
- if (res == -1)
- {
- boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), "boost::asio::posix::basic_signal_handler_service::add_signal: sigaction failed");
- boost::throw_exception(e);
- }
-
- impl->add_signal(signal, oldact);
- }
-
- void remove_signal(implementation_type &impl, int signal)
- {
- impl->remove_signal(signal);
- }
-
- int wait(implementation_type &impl, boost::system::error_code &ec)
- {
- return impl->wait(ec);
- }
-
- template <typename Handler>
- class wait_operation
- {
- public:
- wait_operation(implementation_type &impl, boost::asio::io_service &io_service, Handler handler)
- : impl_(impl),
- io_service_(io_service),
- work_(io_service),
- handler_(handler)
- {
- }
-
- void operator()() const
- {
- implementation_type impl = impl_.lock();
- if (impl)
- {
- boost::system::error_code ec;
- int signal = impl->wait(ec);
- this->io_service_.post(boost::asio::detail::bind_handler(handler_, ec, signal));
- }
- else
- {
- this->io_service_.post(boost::asio::detail::bind_handler(handler_, boost::asio::error::operation_aborted, 0));
- }
- }
-
- private:
- boost::weak_ptr<SignalHandlerImplementation> impl_;
- boost::asio::io_service &io_service_;
- boost::asio::io_service::work work_;
- Handler handler_;
- };
-
- template <typename Handler>
- void async_wait(implementation_type &impl, Handler handler)
- {
- this->async_wait_io_service_.post(wait_operation<Handler>(impl, this->get_io_service(), handler));
- }
-
-private:
- void shutdown_service()
- {
- }
-
- static void signal_handler(int signal)
- {
- while (::write(fd_, &signal, sizeof(signal)) == -1 && errno == EINTR);
- }
-
- static int count_;
- static boost::weak_ptr<SignalHandlerImplementation> impl_;
- static int fd_;
- boost::asio::io_service async_wait_io_service_;
- boost::scoped_ptr<boost::asio::io_service::work> async_wait_work_;
- boost::thread async_wait_thread_;
-};
-
-template <typename SignalHandlerImplementation>
-boost::asio::io_service::id basic_signal_handler_service<SignalHandlerImplementation>::id;
-
-template <typename SignalHandlerImplementation>
-int basic_signal_handler_service<SignalHandlerImplementation>::count_ = 0;
-
-template <typename SignalHandlerImplementation>
-boost::weak_ptr<SignalHandlerImplementation> basic_signal_handler_service<SignalHandlerImplementation>::impl_;
-
-template <typename SignalHandlerImplementation>
-int basic_signal_handler_service<SignalHandlerImplementation>::fd_;
-
-}
-}
-}
-
-#endif
+++ /dev/null
-//
-// Copyright (c) 2009, 2010 Boris Schaeling <boris@highscore.de>
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_ASIO_POSIX_SIGNAL_HANDLER_HPP
-#define BOOST_ASIO_POSIX_SIGNAL_HANDLER_HPP
-
-#include "basic_signal_handler.hpp"
-#include "basic_signal_handler_service.hpp"
-
-namespace boost {
-namespace asio {
-namespace posix {
-
-typedef basic_signal_handler<basic_signal_handler_service<> > signal_handler;
-
-}
-}
-}
-
-#endif
+++ /dev/null
-//
-// Copyright (c) 2009, 2010 Boris Schaeling <boris@highscore.de>
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef BOOST_ASIO_POSIX_SIGNAL_HANDLER_IMPL_HPP
-#define BOOST_ASIO_POSIX_SIGNAL_HANDLER_IMPL_HPP
-
-#include <boost/asio.hpp>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/system/system_error.hpp>
-#include <map>
-#include <deque>
-#include <signal.h>
-#include <unistd.h>
-
-namespace boost {
-namespace asio {
-namespace posix {
-
-class signal_handler_impl
-{
-public:
- signal_handler_impl()
- : sd_(signal_handler_io_service_),
- run_(true)
- {
- int res = pipe(fds_);
- if (res == -1)
- {
- boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), "boost::asio::posix::signal_handler_impl::signal_handler_impl: pipe failed");
- boost::throw_exception(e);
- }
-
- sd_.assign(fds_[0]);
- begin_read();
- signal_handler_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &signal_handler_io_service_));
- }
-
- ~signal_handler_impl()
- {
- for (sigactions_t::iterator it = sigactions_.begin(); it != sigactions_.end(); ++it)
- sigaction(it->first, &it->second, 0);
-
- close(fds_[1]);
- sd_.close();
-
- signal_handler_io_service_.stop();
- signal_handler_thread_.join();
- }
-
- int write_end() const
- {
- return fds_[1];
- }
-
- void add_signal(int signal, struct sigaction oldact)
- {
- sigactions_.insert(sigactions_t::value_type(signal, oldact));
- }
-
- void remove_signal(int signal)
- {
- sigactions_t::iterator it = sigactions_.find(signal);
- if (it != sigactions_.end())
- {
- sigaction(signal, &it->second, 0);
- sigactions_.erase(it);
- }
- }
-
- void destroy()
- {
- boost::unique_lock<boost::mutex> lock(pending_signals_mutex_);
- run_ = false;
- pending_signals_cond_.notify_all();
- }
-
- int wait(boost::system::error_code &ec)
- {
- boost::unique_lock<boost::mutex> lock(pending_signals_mutex_);
- while (run_ && pending_signals_.empty())
- pending_signals_cond_.wait(lock);
- int signal = 0;
- if (!pending_signals_.empty())
- {
- signal = pending_signals_.front();
- pending_signals_.pop_front();
- }
- else
- ec = boost::asio::error::operation_aborted;
- return signal;
- }
-
-private:
- void begin_read()
- {
- boost::asio::async_read(sd_, boost::asio::buffer(signal_buffer_),
- boost::bind(&signal_handler_impl::end_read, this,
- boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
- }
-
- void end_read(const boost::system::error_code &ec, std::size_t bytes_transferred)
- {
- if (!ec)
- {
- boost::unique_lock<boost::mutex> lock(pending_signals_mutex_);
- pending_signals_.push_back(signal_buffer_[0]);
- pending_signals_cond_.notify_all();
- begin_read();
- }
- }
-
- int fds_[2];
- boost::asio::io_service signal_handler_io_service_;
- boost::thread signal_handler_thread_;
- boost::asio::posix::stream_descriptor sd_;
- int signal_buffer_[1];
- typedef std::map<int, struct sigaction> sigactions_t;
- sigactions_t sigactions_;
- boost::mutex pending_signals_mutex_;
- boost::condition_variable_any pending_signals_cond_;
- bool run_;
- std::deque<int> pending_signals_;
-};
-
-}
-}
-}
-
-#endif