Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:43

0001 //
0002 // detail/reactor_op_queue.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
0012 #define BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/hash_map.hpp>
0020 #include <boost/asio/detail/noncopyable.hpp>
0021 #include <boost/asio/detail/op_queue.hpp>
0022 #include <boost/asio/detail/reactor_op.hpp>
0023 #include <boost/asio/error.hpp>
0024 
0025 #include <boost/asio/detail/push_options.hpp>
0026 
0027 namespace boost {
0028 namespace asio {
0029 namespace detail {
0030 
0031 template <typename Descriptor>
0032 class reactor_op_queue
0033   : private noncopyable
0034 {
0035 public:
0036   typedef Descriptor key_type;
0037 
0038   struct mapped_type : op_queue<reactor_op>
0039   {
0040     mapped_type() {}
0041     mapped_type(const mapped_type&) {}
0042     void operator=(const mapped_type&) {}
0043   };
0044 
0045   typedef typename hash_map<key_type, mapped_type>::value_type value_type;
0046   typedef typename hash_map<key_type, mapped_type>::iterator iterator;
0047 
0048   // Constructor.
0049   reactor_op_queue()
0050     : operations_()
0051   {
0052   }
0053 
0054   // Obtain iterators to all registered descriptors.
0055   iterator begin() { return operations_.begin(); }
0056   iterator end() { return operations_.end(); }
0057 
0058   // Add a new operation to the queue. Returns true if this is the only
0059   // operation for the given descriptor, in which case the reactor's event
0060   // demultiplexing function call may need to be interrupted and restarted.
0061   bool enqueue_operation(Descriptor descriptor, reactor_op* op)
0062   {
0063     std::pair<iterator, bool> entry =
0064       operations_.insert(value_type(descriptor, mapped_type()));
0065     entry.first->second.push(op);
0066     return entry.second;
0067   }
0068 
0069   // Cancel all operations associated with the descriptor identified by the
0070   // supplied iterator. Any operations pending for the descriptor will be
0071   // cancelled. Returns true if any operations were cancelled, in which case
0072   // the reactor's event demultiplexing function may need to be interrupted and
0073   // restarted.
0074   bool cancel_operations(iterator i, op_queue<operation>& ops,
0075       const boost::system::error_code& ec =
0076         boost::asio::error::operation_aborted)
0077   {
0078     if (i != operations_.end())
0079     {
0080       while (reactor_op* op = i->second.front())
0081       {
0082         op->ec_ = ec;
0083         i->second.pop();
0084         ops.push(op);
0085       }
0086       operations_.erase(i);
0087       return true;
0088     }
0089 
0090     return false;
0091   }
0092 
0093   // Cancel all operations associated with the descriptor. Any operations
0094   // pending for the descriptor will be cancelled. Returns true if any
0095   // operations were cancelled, in which case the reactor's event
0096   // demultiplexing function may need to be interrupted and restarted.
0097   bool cancel_operations(Descriptor descriptor, op_queue<operation>& ops,
0098       const boost::system::error_code& ec =
0099         boost::asio::error::operation_aborted)
0100   {
0101     return this->cancel_operations(operations_.find(descriptor), ops, ec);
0102   }
0103 
0104   // Cancel operations associated with the descriptor identified by the
0105   // supplied iterator, and the specified cancellation key. Any operations
0106   // pending for the descriptor with the key will be cancelled. Returns true if
0107   // any operations were cancelled, in which case the reactor's event
0108   // demultiplexing function may need to be interrupted and restarted.
0109   bool cancel_operations_by_key(iterator i, op_queue<operation>& ops,
0110       void* cancellation_key, const boost::system::error_code& ec =
0111         boost::asio::error::operation_aborted)
0112   {
0113     bool result = false;
0114     if (i != operations_.end())
0115     {
0116       op_queue<reactor_op> other_ops;
0117       while (reactor_op* op = i->second.front())
0118       {
0119         i->second.pop();
0120         if (op->cancellation_key_ == cancellation_key)
0121         {
0122           op->ec_ = ec;
0123           ops.push(op);
0124           result = true;
0125         }
0126         else
0127           other_ops.push(op);
0128       }
0129       i->second.push(other_ops);
0130       if (i->second.empty())
0131         operations_.erase(i);
0132     }
0133     return result;
0134   }
0135 
0136   // Cancel all operations associated with the descriptor. Any operations
0137   // pending for the descriptor will be cancelled. Returns true if any
0138   // operations were cancelled, in which case the reactor's event
0139   // demultiplexing function may need to be interrupted and restarted.
0140   bool cancel_operations_by_key(Descriptor descriptor, op_queue<operation>& ops,
0141       void* cancellation_key, const boost::system::error_code& ec =
0142         boost::asio::error::operation_aborted)
0143   {
0144     return this->cancel_operations_by_key(
0145         operations_.find(descriptor), ops, cancellation_key, ec);
0146   }
0147 
0148   // Whether there are no operations in the queue.
0149   bool empty() const
0150   {
0151     return operations_.empty();
0152   }
0153 
0154   // Determine whether there are any operations associated with the descriptor.
0155   bool has_operation(Descriptor descriptor) const
0156   {
0157     return operations_.find(descriptor) != operations_.end();
0158   }
0159 
0160   // Perform the operations corresponding to the descriptor identified by the
0161   // supplied iterator. Returns true if there are still unfinished operations
0162   // queued for the descriptor.
0163   bool perform_operations(iterator i, op_queue<operation>& ops)
0164   {
0165     if (i != operations_.end())
0166     {
0167       while (reactor_op* op = i->second.front())
0168       {
0169         if (op->perform())
0170         {
0171           i->second.pop();
0172           ops.push(op);
0173         }
0174         else
0175         {
0176           return true;
0177         }
0178       }
0179       operations_.erase(i);
0180     }
0181     return false;
0182   }
0183 
0184   // Perform the operations corresponding to the descriptor. Returns true if
0185   // there are still unfinished operations queued for the descriptor.
0186   bool perform_operations(Descriptor descriptor, op_queue<operation>& ops)
0187   {
0188     return this->perform_operations(operations_.find(descriptor), ops);
0189   }
0190 
0191   // Get all operations owned by the queue.
0192   void get_all_operations(op_queue<operation>& ops)
0193   {
0194     iterator i = operations_.begin();
0195     while (i != operations_.end())
0196     {
0197       iterator op_iter = i++;
0198       ops.push(op_iter->second);
0199       operations_.erase(op_iter);
0200     }
0201   }
0202 
0203 private:
0204   // The operations that are currently executing asynchronously.
0205   hash_map<key_type, mapped_type> operations_;
0206 };
0207 
0208 } // namespace detail
0209 } // namespace asio
0210 } // namespace boost
0211 
0212 #include <boost/asio/detail/pop_options.hpp>
0213 
0214 #endif // BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP