//
// detail/reactor_op_queue.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2010 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 BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
#define BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/hash_map.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/op_queue.hpp>
#include <boost/asio/detail/reactor_op.hpp>
#include <boost/asio/error.hpp>

#include <boost/asio/detail/push_options.hpp>

namespace boost {
namespace asio {
namespace detail {

template <typename Descriptor>
class reactor_op_queue
  : private noncopyable
{
public:
  // Constructor.
  reactor_op_queue()
    : operations_()
  {
  }

  // 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)
  {
    typedef typename operations_map::iterator iterator;
    typedef typename operations_map::value_type value_type;
    std::pair<iterator, bool> entry =
      operations_.insert(value_type(descriptor, operations()));
    entry.first->second.op_queue_.push(op);
    return entry.second;
  }

  // Cancel all operations associated with the descriptor. Any operations
  // pending for the descriptor will be notified that they have been cancelled
  // next time perform_cancellations is called. 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 boost::system::error_code& ec =
        boost::asio::error::operation_aborted)
  {
    typename operations_map::iterator i = operations_.find(descriptor);
    if (i != operations_.end())
    {
      while (reactor_op* op = i->second.op_queue_.front())
      {
        op->ec_ = ec;
        i->second.op_queue_.pop();
        ops.push(op);
      }
      operations_.erase(i);
      return true;
    }

    return false;
  }

  // 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. Returns true if
  // there are still unfinished operations queued for the descriptor.
  bool perform_operations(Descriptor descriptor, op_queue<operation>& ops)
  {
    typename operations_map::iterator i = operations_.find(descriptor);
    if (i != operations_.end())
    {
      while (reactor_op* op = i->second.op_queue_.front())
      {
        if (op->perform())
        {
          i->second.op_queue_.pop();
          ops.push(op);
        }
        else
        {
          return true;
        }
      }
      operations_.erase(i);
    }
    return false;
  }

  // Fill a descriptor set with the descriptors corresponding to each active
  // operation. The op_queue is used only when descriptors fail to be added to
  // the descriptor set.
  template <typename Descriptor_Set>
  void get_descriptors(Descriptor_Set& descriptors, op_queue<operation>& ops)
  {
    typename operations_map::iterator i = operations_.begin();
    while (i != operations_.end())
    {
      Descriptor descriptor = i->first;
      ++i;
      if (!descriptors.set(descriptor))
      {
        boost::system::error_code ec(error::fd_set_failure);
        cancel_operations(descriptor, ops, ec);
      }
    }
  }

  // Perform the operations corresponding to the ready file descriptors
  // contained in the given descriptor set.
  template <typename Descriptor_Set>
  void perform_operations_for_descriptors(
      const Descriptor_Set& descriptors, op_queue<operation>& ops)
  {
    typename operations_map::iterator i = operations_.begin();
    while (i != operations_.end())
    {
      typename operations_map::iterator op_iter = i++;
      if (descriptors.is_set(op_iter->first))
      {
        while (reactor_op* op = op_iter->second.op_queue_.front())
        {
          if (op->perform())
          {
            op_iter->second.op_queue_.pop();
            ops.push(op);
          }
          else
          {
            break;
          }
        }

        if (op_iter->second.op_queue_.empty())
          operations_.erase(op_iter);
      }
    }
  }

  // Get all operations owned by the queue.
  void get_all_operations(op_queue<operation>& ops)
  {
    typename operations_map::iterator i = operations_.begin();
    while (i != operations_.end())
    {
      typename operations_map::iterator op_iter = i++;
      ops.push(op_iter->second.op_queue_);
      operations_.erase(op_iter);
    }
  }

private:
  struct operations
  {
    operations() {}
    operations(const operations&) {}
    void operator=(const operations&) {}

    // The operations waiting on the desccriptor.
    op_queue<reactor_op> op_queue_;
  };

  // The type for a map of operations.
  typedef hash_map<Descriptor, operations> operations_map;

  // The operations that are currently executing asynchronously.
  operations_map operations_;
};

} // namespace detail
} // namespace asio
} // namespace boost

#include <boost/asio/detail/pop_options.hpp>

#endif // BOOST_ASIO_DETAIL_REACTOR_OP_QUEUE_HPP
