Chris@16: // Chris@16: // detail/reactor_op_queue.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP Chris@16: #define BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: template Chris@16: class reactor_op_queue Chris@16: : private noncopyable Chris@16: { Chris@16: public: Chris@101: typedef Descriptor key_type; Chris@101: Chris@101: struct mapped_type : op_queue Chris@101: { Chris@101: mapped_type() {} Chris@101: mapped_type(const mapped_type&) {} Chris@101: void operator=(const mapped_type&) {} Chris@101: }; Chris@101: Chris@101: typedef typename hash_map::value_type value_type; Chris@101: typedef typename hash_map::iterator iterator; Chris@101: Chris@16: // Constructor. Chris@16: reactor_op_queue() Chris@16: : operations_() Chris@16: { Chris@16: } Chris@16: Chris@101: // Obtain iterators to all registered descriptors. Chris@101: iterator begin() { return operations_.begin(); } Chris@101: iterator end() { return operations_.end(); } Chris@101: Chris@16: // Add a new operation to the queue. Returns true if this is the only Chris@16: // operation for the given descriptor, in which case the reactor's event Chris@16: // demultiplexing function call may need to be interrupted and restarted. Chris@16: bool enqueue_operation(Descriptor descriptor, reactor_op* op) Chris@16: { Chris@16: std::pair entry = Chris@101: operations_.insert(value_type(descriptor, mapped_type())); Chris@101: entry.first->second.push(op); Chris@16: return entry.second; Chris@16: } Chris@16: Chris@101: // Cancel all operations associated with the descriptor identified by the Chris@101: // supplied iterator. Any operations pending for the descriptor will be Chris@101: // cancelled. Returns true if any operations were cancelled, in which case Chris@101: // the reactor's event demultiplexing function may need to be interrupted and Chris@101: // restarted. Chris@101: bool cancel_operations(iterator i, op_queue& ops, Chris@16: const boost::system::error_code& ec = Chris@16: boost::asio::error::operation_aborted) Chris@16: { Chris@16: if (i != operations_.end()) Chris@16: { Chris@101: while (reactor_op* op = i->second.front()) Chris@16: { Chris@16: op->ec_ = ec; Chris@101: i->second.pop(); Chris@16: ops.push(op); Chris@16: } Chris@16: operations_.erase(i); Chris@16: return true; Chris@16: } Chris@16: Chris@16: return false; Chris@16: } Chris@16: Chris@101: // Cancel all operations associated with the descriptor. Any operations Chris@101: // pending for the descriptor will be cancelled. Returns true if any Chris@101: // operations were cancelled, in which case the reactor's event Chris@101: // demultiplexing function may need to be interrupted and restarted. Chris@101: bool cancel_operations(Descriptor descriptor, op_queue& ops, Chris@101: const boost::system::error_code& ec = Chris@101: boost::asio::error::operation_aborted) Chris@101: { Chris@101: return this->cancel_operations(operations_.find(descriptor), ops, ec); Chris@101: } Chris@101: Chris@16: // Whether there are no operations in the queue. Chris@16: bool empty() const Chris@16: { Chris@16: return operations_.empty(); Chris@16: } Chris@16: Chris@16: // Determine whether there are any operations associated with the descriptor. Chris@16: bool has_operation(Descriptor descriptor) const Chris@16: { Chris@16: return operations_.find(descriptor) != operations_.end(); Chris@16: } Chris@16: Chris@101: // Perform the operations corresponding to the descriptor identified by the Chris@101: // supplied iterator. Returns true if there are still unfinished operations Chris@101: // queued for the descriptor. Chris@101: bool perform_operations(iterator i, op_queue& ops) Chris@16: { Chris@16: if (i != operations_.end()) Chris@16: { Chris@101: while (reactor_op* op = i->second.front()) Chris@16: { Chris@16: if (op->perform()) Chris@16: { Chris@101: i->second.pop(); Chris@16: ops.push(op); Chris@16: } Chris@16: else Chris@16: { Chris@16: return true; Chris@16: } Chris@16: } Chris@16: operations_.erase(i); Chris@16: } Chris@16: return false; Chris@16: } Chris@16: Chris@101: // Perform the operations corresponding to the descriptor. Returns true if Chris@101: // there are still unfinished operations queued for the descriptor. Chris@101: bool perform_operations(Descriptor descriptor, op_queue& ops) Chris@16: { Chris@101: return this->perform_operations(operations_.find(descriptor), ops); Chris@16: } Chris@16: Chris@16: // Get all operations owned by the queue. Chris@16: void get_all_operations(op_queue& ops) Chris@16: { Chris@101: iterator i = operations_.begin(); Chris@16: while (i != operations_.end()) Chris@16: { Chris@101: iterator op_iter = i++; Chris@101: ops.push(op_iter->second); Chris@16: operations_.erase(op_iter); Chris@16: } Chris@16: } Chris@16: Chris@16: private: Chris@16: // The operations that are currently executing asynchronously. Chris@101: hash_map operations_; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP