123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- //
- // detail/reactor_op_queue.hpp
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
- //
- // 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 ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
- #define ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include "asio/detail/config.hpp"
- #include "asio/detail/hash_map.hpp"
- #include "asio/detail/noncopyable.hpp"
- #include "asio/detail/op_queue.hpp"
- #include "asio/detail/reactor_op.hpp"
- #include "asio/error.hpp"
- #include "asio/detail/push_options.hpp"
- namespace asio {
- namespace detail {
- template <typename Descriptor>
- class reactor_op_queue
- : private noncopyable
- {
- public:
- typedef Descriptor key_type;
- struct mapped_type : op_queue<reactor_op>
- {
- mapped_type() {}
- mapped_type(const mapped_type&) {}
- void operator=(const mapped_type&) {}
- };
- typedef typename hash_map<key_type, mapped_type>::value_type value_type;
- typedef typename hash_map<key_type, mapped_type>::iterator iterator;
- // Constructor.
- reactor_op_queue()
- : operations_()
- {
- }
- // Obtain iterators to all registered descriptors.
- iterator begin() { return operations_.begin(); }
- iterator end() { return operations_.end(); }
- // Add a new operation to the queue. Returns true if this is the only
- // operation for the given descriptor, in which case the reactor's event
- // demultiplexing function call may need to be interrupted and restarted.
- bool enqueue_operation(Descriptor descriptor, reactor_op* op)
- {
- std::pair<iterator, bool> entry =
- operations_.insert(value_type(descriptor, mapped_type()));
- entry.first->second.push(op);
- return entry.second;
- }
- // Cancel all operations associated with the descriptor identified by the
- // supplied iterator. Any operations pending for the descriptor will be
- // cancelled. Returns true if any operations were cancelled, in which case
- // the reactor's event demultiplexing function may need to be interrupted and
- // restarted.
- bool cancel_operations(iterator i, op_queue<operation>& ops,
- const asio::error_code& ec =
- asio::error::operation_aborted)
- {
- if (i != operations_.end())
- {
- while (reactor_op* op = i->second.front())
- {
- op->ec_ = ec;
- i->second.pop();
- ops.push(op);
- }
- operations_.erase(i);
- return true;
- }
- return false;
- }
- // Cancel all operations associated with the descriptor. Any operations
- // pending for the descriptor will be cancelled. Returns true if any
- // operations were cancelled, in which case the reactor's event
- // demultiplexing function may need to be interrupted and restarted.
- bool cancel_operations(Descriptor descriptor, op_queue<operation>& ops,
- const asio::error_code& ec =
- asio::error::operation_aborted)
- {
- return this->cancel_operations(operations_.find(descriptor), ops, ec);
- }
- // Cancel operations associated with the descriptor identified by the
- // supplied iterator, and the specified cancellation key. Any operations
- // pending for the descriptor with the key will be cancelled. Returns true if
- // any operations were cancelled, in which case the reactor's event
- // demultiplexing function may need to be interrupted and restarted.
- bool cancel_operations_by_key(iterator i, op_queue<operation>& ops,
- void* cancellation_key, const asio::error_code& ec =
- asio::error::operation_aborted)
- {
- bool result = false;
- if (i != operations_.end())
- {
- op_queue<reactor_op> other_ops;
- while (reactor_op* op = i->second.front())
- {
- i->second.pop();
- if (op->cancellation_key_ == cancellation_key)
- {
- op->ec_ = ec;
- ops.push(op);
- result = true;
- }
- else
- other_ops.push(op);
- }
- i->second.push(other_ops);
- if (i->second.empty())
- operations_.erase(i);
- }
- return result;
- }
- // Cancel all operations associated with the descriptor. Any operations
- // pending for the descriptor will be cancelled. Returns true if any
- // operations were cancelled, in which case the reactor's event
- // demultiplexing function may need to be interrupted and restarted.
- bool cancel_operations_by_key(Descriptor descriptor, op_queue<operation>& ops,
- void* cancellation_key, const asio::error_code& ec =
- asio::error::operation_aborted)
- {
- return this->cancel_operations_by_key(
- operations_.find(descriptor), ops, cancellation_key, ec);
- }
- // Whether there are no operations in the queue.
- bool empty() const
- {
- return operations_.empty();
- }
- // Determine whether there are any operations associated with the descriptor.
- bool has_operation(Descriptor descriptor) const
- {
- return operations_.find(descriptor) != operations_.end();
- }
- // Perform the operations corresponding to the descriptor identified by the
- // supplied iterator. Returns true if there are still unfinished operations
- // queued for the descriptor.
- bool perform_operations(iterator i, op_queue<operation>& ops)
- {
- if (i != operations_.end())
- {
- while (reactor_op* op = i->second.front())
- {
- if (op->perform())
- {
- i->second.pop();
- ops.push(op);
- }
- else
- {
- return true;
- }
- }
- operations_.erase(i);
- }
- return false;
- }
- // Perform the operations corresponding to the descriptor. Returns true if
- // there are still unfinished operations queued for the descriptor.
- bool perform_operations(Descriptor descriptor, op_queue<operation>& ops)
- {
- return this->perform_operations(operations_.find(descriptor), ops);
- }
- // Get all operations owned by the queue.
- void get_all_operations(op_queue<operation>& ops)
- {
- iterator i = operations_.begin();
- while (i != operations_.end())
- {
- iterator op_iter = i++;
- ops.push(op_iter->second);
- operations_.erase(op_iter);
- }
- }
- private:
- // The operations that are currently executing asynchronously.
- hash_map<key_type, mapped_type> operations_;
- };
- } // namespace detail
- } // namespace asio
- #include "asio/detail/pop_options.hpp"
- #endif // ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
|