Author: andar

Revision: 5107

Log:
        Add missing files

Diff:
Added: 
branches/1.1.0_RC/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp
===================================================================
--- 
branches/1.1.0_RC/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp 
                            (rev 0)
+++ 
branches/1.1.0_RC/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp 
    2009-04-20 22:01:52 UTC (rev 5107)
@@ -0,0 +1,155 @@
+//
+// eventfd_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail 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_EVENTFD_SELECT_INTERRUPTER_HPP
+#define ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/detail/push_options.hpp"
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include "asio/detail/pop_options.hpp"
+
+#if defined(linux)
+# if !defined(ASIO_DISABLE_EVENTFD)
+#  include <linux/version.h>
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#   define ASIO_HAS_EVENTFD
+#  endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+# endif // !defined(ASIO_DISABLE_EVENTFD)
+#endif // defined(linux)
+
+#if defined(ASIO_HAS_EVENTFD)
+
+#include "asio/detail/push_options.hpp"
+#include <fcntl.h>
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <asm/unistd.h>
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <sys/eventfd.h>
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+#include "asio/detail/pop_options.hpp"
+
+#include "asio/error.hpp"
+#include "asio/system_error.hpp"
+#include "asio/detail/socket_types.hpp"
+
+namespace asio {
+namespace detail {
+
+class eventfd_select_interrupter
+{
+public:
+  // Constructor.
+  eventfd_select_interrupter()
+  {
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    if (read_descriptor_ != -1)
+    {
+      ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+    }
+    else
+    {
+      int pipe_fds[2];
+      if (pipe(pipe_fds) == 0)
+      {
+        read_descriptor_ = pipe_fds[0];
+        ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+        write_descriptor_ = pipe_fds[1];
+        ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+      }
+      else
+      {
+        asio::error_code ec(errno,
+            asio::error::get_system_category());
+        asio::system_error e(ec, "eventfd_select_interrupter");
+        boost::throw_exception(e);
+      }
+    }
+  }
+
+  // Destructor.
+  ~eventfd_select_interrupter()
+  {
+    if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_)
+      ::close(write_descriptor_);
+    if (read_descriptor_ != -1)
+      ::close(read_descriptor_);
+  }
+
+  // Interrupt the select call.
+  void interrupt()
+  {
+    uint64_t counter(1UL);
+    int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
+    (void)result;
+  }
+
+  // Reset the select interrupt. Returns true if the call was interrupted.
+  bool reset()
+  {
+    if (write_descriptor_ == read_descriptor_)
+    {
+      // Only perform one read. The kernel maintains an atomic counter.
+      uint64_t counter(0);
+      int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
+      bool was_interrupted = (bytes_read > 0);
+      return was_interrupted;
+    }
+    else
+    {
+      // Clear all data from the pipe.
+      char data[1024];
+      int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      bool was_interrupted = (bytes_read > 0);
+      while (bytes_read == sizeof(data))
+        bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      return was_interrupted;
+    }
+  }
+
+  // Get the read descriptor to be passed to select.
+  int read_descriptor() const
+  {
+    return read_descriptor_;
+  }
+
+private:
+  // The read end of a connection used to interrupt the select call. This file
+  // descriptor is passed to select such that when it is time to stop, a single
+  // 64bit value will be written on the other end of the connection and this
+  // descriptor will become readable.
+  int read_descriptor_;
+
+  // The write end of a connection used to interrupt the select call. A single
+  // 64bit non-zero value may be written to this to wake up the select which is
+  // waiting for the other end to become readable. This descriptor will only
+  // differ from the read descriptor when a pipe is used.
+  int write_descriptor_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#endif // defined(ASIO_HAS_EVENTFD)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP

Added: 
branches/1.1.0_RC/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp
===================================================================
--- 
branches/1.1.0_RC/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp    
                            (rev 0)
+++ 
branches/1.1.0_RC/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp    
    2009-04-20 22:01:52 UTC (rev 5107)
@@ -0,0 +1,207 @@
+//
+// win_iocp_overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 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_WIN_IOCP_OVERLAPPED_PTR_HPP
+#define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/detail/win_iocp_io_service_fwd.hpp"
+
+#if defined(ASIO_HAS_IOCP)
+
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/win_iocp_io_service.hpp"
+
+namespace asio {
+namespace detail {
+
+// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O.
+class win_iocp_overlapped_ptr
+  : private noncopyable
+{
+public:
+  // Construct an empty win_iocp_overlapped_ptr.
+  win_iocp_overlapped_ptr()
+    : ptr_(0)
+  {
+  }
+
+  // Construct an win_iocp_overlapped_ptr to contain the specified handler.
+  template <typename Handler>
+  explicit win_iocp_overlapped_ptr(
+      asio::io_service& io_service, Handler handler)
+    : ptr_(0)
+  {
+    this->reset(io_service, handler);
+  }
+
+  // Destructor automatically frees the OVERLAPPED object unless released.
+  ~win_iocp_overlapped_ptr()
+  {
+    reset();
+  }
+
+  // Reset to empty.
+  void reset()
+  {
+    if (ptr_)
+    {
+      ptr_->destroy();
+      ptr_ = 0;
+    }
+  }
+
+  // Reset to contain the specified handler, freeing any current OVERLAPPED
+  // object.
+  template <typename Handler>
+  void reset(asio::io_service& io_service, Handler handler)
+  {
+    typedef overlapped_operation<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, io_service.impl_, handler);
+    reset();
+    ptr_ = ptr.release();
+  }
+
+  // Get the contained OVERLAPPED object.
+  OVERLAPPED* get()
+  {
+    return ptr_;
+  }
+
+  // Get the contained OVERLAPPED object.
+  const OVERLAPPED* get() const
+  {
+    return ptr_;
+  }
+
+  // Release ownership of the OVERLAPPED object.
+  OVERLAPPED* release()
+  {
+    OVERLAPPED* tmp = ptr_;
+    ptr_ = 0;
+    return tmp;
+  }
+
+  // Post completion notification for overlapped operation. Releases ownership.
+  void complete(const asio::error_code& ec,
+      std::size_t bytes_transferred)
+  {
+    if (ptr_)
+    {
+      ptr_->ec_ = ec;
+      ptr_->io_service_.post_completion(ptr_, 0, bytes_transferred);
+      ptr_ = 0;
+    }
+  }
+
+private:
+  struct overlapped_operation_base
+    : public win_iocp_io_service::operation
+  {
+    overlapped_operation_base(win_iocp_io_service& io_service,
+        invoke_func_type invoke_func, destroy_func_type destroy_func)
+      : win_iocp_io_service::operation(io_service, invoke_func, destroy_func),
+        io_service_(io_service)
+    {
+      io_service_.work_started();
+    }
+
+    ~overlapped_operation_base()
+    {
+      io_service_.work_finished();
+    }
+
+    win_iocp_io_service& io_service_;
+    asio::error_code ec_;
+  };
+
+  template <typename Handler>
+  struct overlapped_operation
+    : public overlapped_operation_base
+  {
+    overlapped_operation(win_iocp_io_service& io_service,
+        Handler handler)
+      : overlapped_operation_base(io_service,
+          &overlapped_operation<Handler>::do_completion_impl,
+          &overlapped_operation<Handler>::destroy_impl),
+        handler_(handler)
+    {
+    }
+
+  private:
+    // Prevent copying and assignment.
+    overlapped_operation(const overlapped_operation&);
+    void operator=(const overlapped_operation&);
+    
+    static void do_completion_impl(win_iocp_io_service::operation* op,
+        DWORD last_error, size_t bytes_transferred)
+    {
+      // Take ownership of the operation object.
+      typedef overlapped_operation<Handler> op_type;
+      op_type* handler_op(static_cast<op_type*>(op));
+      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
+      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+
+      // Make a copy of the handler and error_code so that the memory can be
+      // deallocated before the upcall is made.
+      Handler handler(handler_op->handler_);
+      asio::error_code ec(handler_op->ec_);
+      if (last_error)
+        ec = asio::error_code(last_error,
+            asio::error::get_system_category());
+
+      // Free the memory associated with the handler.
+      ptr.reset();
+
+      // Make the upcall.
+      asio_handler_invoke_helpers::invoke(
+          bind_handler(handler, ec, bytes_transferred), &handler);
+    }
+
+    static void destroy_impl(win_iocp_io_service::operation* op)
+    {
+      // Take ownership of the operation object.
+      typedef overlapped_operation<Handler> op_type;
+      op_type* handler_op(static_cast<op_type*>(op));
+      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
+      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+
+      // A sub-object of the handler may be the true owner of the memory
+      // associated with the handler. Consequently, a local copy of the handler
+      // is required to ensure that any owning sub-object remains valid until
+      // after we have deallocated the memory here.
+      Handler handler(handler_op->handler_);
+      (void)handler;
+
+      // Free the memory associated with the handler.
+      ptr.reset();
+    }
+
+    Handler handler_;
+  };
+
+  overlapped_operation_base* ptr_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#endif // defined(ASIO_HAS_IOCP)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP

Added: branches/1.1.0_RC/libtorrent/include/asio/windows/overlapped_ptr.hpp
===================================================================
--- branches/1.1.0_RC/libtorrent/include/asio/windows/overlapped_ptr.hpp        
                        (rev 0)
+++ branches/1.1.0_RC/libtorrent/include/asio/windows/overlapped_ptr.hpp        
2009-04-20 22:01:52 UTC (rev 5107)
@@ -0,0 +1,118 @@
+//
+// overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 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_WINDOWS_OVERLAPPED_PTR_HPP
+#define ASIO_WINDOWS_OVERLAPPED_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/io_service.hpp"
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/win_iocp_overlapped_ptr.hpp"
+
+#if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+# if defined(ASIO_HAS_IOCP)
+#  define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1
+# endif // defined(ASIO_HAS_IOCP)
+#endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+
+#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace asio {
+namespace windows {
+
+/// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O.
+/**
+ * A special-purpose smart pointer used to wrap an application handler so that
+ * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: sa...@n
+ * @e Shared @e objects: Unsafe.
+ */
+class overlapped_ptr
+  : private noncopyable
+{
+public:
+  /// Construct an empty overlapped_ptr.
+  overlapped_ptr()
+    : impl_()
+  {
+  }
+
+  /// Construct an overlapped_ptr to contain the specified handler.
+  template <typename Handler>
+  explicit overlapped_ptr(asio::io_service& io_service, Handler handler)
+    : impl_(io_service, handler)
+  {
+  }
+
+  /// Destructor automatically frees the OVERLAPPED object unless released.
+  ~overlapped_ptr()
+  {
+  }
+
+  /// Reset to empty.
+  void reset()
+  {
+    impl_.reset();
+  }
+
+  /// Reset to contain the specified handler, freeing any current OVERLAPPED
+  /// object.
+  template <typename Handler>
+  void reset(asio::io_service& io_service, Handler handler)
+  {
+    impl_.reset(io_service, handler);
+  }
+
+  /// Get the contained OVERLAPPED object.
+  OVERLAPPED* get()
+  {
+    return impl_.get();
+  }
+
+  /// Get the contained OVERLAPPED object.
+  const OVERLAPPED* get() const
+  {
+    return impl_.get();
+  }
+
+  /// Release ownership of the OVERLAPPED object.
+  OVERLAPPED* release()
+  {
+    return impl_.release();
+  }
+
+  /// Post completion notification for overlapped operation. Releases 
ownership.
+  void complete(const asio::error_code& ec,
+      std::size_t bytes_transferred)
+  {
+    impl_.complete(ec, bytes_transferred);
+  }
+
+private:
+  detail::win_iocp_overlapped_ptr impl_;
+};
+
+} // namespace windows
+} // namespace asio
+
+#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP

Added: trunk/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp
===================================================================
--- trunk/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp         
                (rev 0)
+++ trunk/libtorrent/include/asio/detail/eventfd_select_interrupter.hpp 
2009-04-20 22:01:52 UTC (rev 5107)
@@ -0,0 +1,155 @@
+//
+// eventfd_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail 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_EVENTFD_SELECT_INTERRUPTER_HPP
+#define ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/detail/push_options.hpp"
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include "asio/detail/pop_options.hpp"
+
+#if defined(linux)
+# if !defined(ASIO_DISABLE_EVENTFD)
+#  include <linux/version.h>
+#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#   define ASIO_HAS_EVENTFD
+#  endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+# endif // !defined(ASIO_DISABLE_EVENTFD)
+#endif // defined(linux)
+
+#if defined(ASIO_HAS_EVENTFD)
+
+#include "asio/detail/push_options.hpp"
+#include <fcntl.h>
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <asm/unistd.h>
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <sys/eventfd.h>
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+#include "asio/detail/pop_options.hpp"
+
+#include "asio/error.hpp"
+#include "asio/system_error.hpp"
+#include "asio/detail/socket_types.hpp"
+
+namespace asio {
+namespace detail {
+
+class eventfd_select_interrupter
+{
+public:
+  // Constructor.
+  eventfd_select_interrupter()
+  {
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+    if (read_descriptor_ != -1)
+    {
+      ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+    }
+    else
+    {
+      int pipe_fds[2];
+      if (pipe(pipe_fds) == 0)
+      {
+        read_descriptor_ = pipe_fds[0];
+        ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+        write_descriptor_ = pipe_fds[1];
+        ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+      }
+      else
+      {
+        asio::error_code ec(errno,
+            asio::error::get_system_category());
+        asio::system_error e(ec, "eventfd_select_interrupter");
+        boost::throw_exception(e);
+      }
+    }
+  }
+
+  // Destructor.
+  ~eventfd_select_interrupter()
+  {
+    if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_)
+      ::close(write_descriptor_);
+    if (read_descriptor_ != -1)
+      ::close(read_descriptor_);
+  }
+
+  // Interrupt the select call.
+  void interrupt()
+  {
+    uint64_t counter(1UL);
+    int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
+    (void)result;
+  }
+
+  // Reset the select interrupt. Returns true if the call was interrupted.
+  bool reset()
+  {
+    if (write_descriptor_ == read_descriptor_)
+    {
+      // Only perform one read. The kernel maintains an atomic counter.
+      uint64_t counter(0);
+      int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
+      bool was_interrupted = (bytes_read > 0);
+      return was_interrupted;
+    }
+    else
+    {
+      // Clear all data from the pipe.
+      char data[1024];
+      int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      bool was_interrupted = (bytes_read > 0);
+      while (bytes_read == sizeof(data))
+        bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      return was_interrupted;
+    }
+  }
+
+  // Get the read descriptor to be passed to select.
+  int read_descriptor() const
+  {
+    return read_descriptor_;
+  }
+
+private:
+  // The read end of a connection used to interrupt the select call. This file
+  // descriptor is passed to select such that when it is time to stop, a single
+  // 64bit value will be written on the other end of the connection and this
+  // descriptor will become readable.
+  int read_descriptor_;
+
+  // The write end of a connection used to interrupt the select call. A single
+  // 64bit non-zero value may be written to this to wake up the select which is
+  // waiting for the other end to become readable. This descriptor will only
+  // differ from the read descriptor when a pipe is used.
+  int write_descriptor_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#endif // defined(ASIO_HAS_EVENTFD)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP

Added: trunk/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp
===================================================================
--- trunk/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp            
                (rev 0)
+++ trunk/libtorrent/include/asio/detail/win_iocp_overlapped_ptr.hpp    
2009-04-20 22:01:52 UTC (rev 5107)
@@ -0,0 +1,207 @@
+//
+// win_iocp_overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 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_WIN_IOCP_OVERLAPPED_PTR_HPP
+#define ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/detail/win_iocp_io_service_fwd.hpp"
+
+#if defined(ASIO_HAS_IOCP)
+
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/win_iocp_io_service.hpp"
+
+namespace asio {
+namespace detail {
+
+// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O.
+class win_iocp_overlapped_ptr
+  : private noncopyable
+{
+public:
+  // Construct an empty win_iocp_overlapped_ptr.
+  win_iocp_overlapped_ptr()
+    : ptr_(0)
+  {
+  }
+
+  // Construct an win_iocp_overlapped_ptr to contain the specified handler.
+  template <typename Handler>
+  explicit win_iocp_overlapped_ptr(
+      asio::io_service& io_service, Handler handler)
+    : ptr_(0)
+  {
+    this->reset(io_service, handler);
+  }
+
+  // Destructor automatically frees the OVERLAPPED object unless released.
+  ~win_iocp_overlapped_ptr()
+  {
+    reset();
+  }
+
+  // Reset to empty.
+  void reset()
+  {
+    if (ptr_)
+    {
+      ptr_->destroy();
+      ptr_ = 0;
+    }
+  }
+
+  // Reset to contain the specified handler, freeing any current OVERLAPPED
+  // object.
+  template <typename Handler>
+  void reset(asio::io_service& io_service, Handler handler)
+  {
+    typedef overlapped_operation<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, io_service.impl_, handler);
+    reset();
+    ptr_ = ptr.release();
+  }
+
+  // Get the contained OVERLAPPED object.
+  OVERLAPPED* get()
+  {
+    return ptr_;
+  }
+
+  // Get the contained OVERLAPPED object.
+  const OVERLAPPED* get() const
+  {
+    return ptr_;
+  }
+
+  // Release ownership of the OVERLAPPED object.
+  OVERLAPPED* release()
+  {
+    OVERLAPPED* tmp = ptr_;
+    ptr_ = 0;
+    return tmp;
+  }
+
+  // Post completion notification for overlapped operation. Releases ownership.
+  void complete(const asio::error_code& ec,
+      std::size_t bytes_transferred)
+  {
+    if (ptr_)
+    {
+      ptr_->ec_ = ec;
+      ptr_->io_service_.post_completion(ptr_, 0, bytes_transferred);
+      ptr_ = 0;
+    }
+  }
+
+private:
+  struct overlapped_operation_base
+    : public win_iocp_io_service::operation
+  {
+    overlapped_operation_base(win_iocp_io_service& io_service,
+        invoke_func_type invoke_func, destroy_func_type destroy_func)
+      : win_iocp_io_service::operation(io_service, invoke_func, destroy_func),
+        io_service_(io_service)
+    {
+      io_service_.work_started();
+    }
+
+    ~overlapped_operation_base()
+    {
+      io_service_.work_finished();
+    }
+
+    win_iocp_io_service& io_service_;
+    asio::error_code ec_;
+  };
+
+  template <typename Handler>
+  struct overlapped_operation
+    : public overlapped_operation_base
+  {
+    overlapped_operation(win_iocp_io_service& io_service,
+        Handler handler)
+      : overlapped_operation_base(io_service,
+          &overlapped_operation<Handler>::do_completion_impl,
+          &overlapped_operation<Handler>::destroy_impl),
+        handler_(handler)
+    {
+    }
+
+  private:
+    // Prevent copying and assignment.
+    overlapped_operation(const overlapped_operation&);
+    void operator=(const overlapped_operation&);
+    
+    static void do_completion_impl(win_iocp_io_service::operation* op,
+        DWORD last_error, size_t bytes_transferred)
+    {
+      // Take ownership of the operation object.
+      typedef overlapped_operation<Handler> op_type;
+      op_type* handler_op(static_cast<op_type*>(op));
+      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
+      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+
+      // Make a copy of the handler and error_code so that the memory can be
+      // deallocated before the upcall is made.
+      Handler handler(handler_op->handler_);
+      asio::error_code ec(handler_op->ec_);
+      if (last_error)
+        ec = asio::error_code(last_error,
+            asio::error::get_system_category());
+
+      // Free the memory associated with the handler.
+      ptr.reset();
+
+      // Make the upcall.
+      asio_handler_invoke_helpers::invoke(
+          bind_handler(handler, ec, bytes_transferred), &handler);
+    }
+
+    static void destroy_impl(win_iocp_io_service::operation* op)
+    {
+      // Take ownership of the operation object.
+      typedef overlapped_operation<Handler> op_type;
+      op_type* handler_op(static_cast<op_type*>(op));
+      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
+      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+
+      // A sub-object of the handler may be the true owner of the memory
+      // associated with the handler. Consequently, a local copy of the handler
+      // is required to ensure that any owning sub-object remains valid until
+      // after we have deallocated the memory here.
+      Handler handler(handler_op->handler_);
+      (void)handler;
+
+      // Free the memory associated with the handler.
+      ptr.reset();
+    }
+
+    Handler handler_;
+  };
+
+  overlapped_operation_base* ptr_;
+};
+
+} // namespace detail
+} // namespace asio
+
+#endif // defined(ASIO_HAS_IOCP)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP

Added: trunk/libtorrent/include/asio/windows/overlapped_ptr.hpp
===================================================================
--- trunk/libtorrent/include/asio/windows/overlapped_ptr.hpp                    
        (rev 0)
+++ trunk/libtorrent/include/asio/windows/overlapped_ptr.hpp    2009-04-20 
22:01:52 UTC (rev 5107)
@@ -0,0 +1,118 @@
+//
+// overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 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_WINDOWS_OVERLAPPED_PTR_HPP
+#define ASIO_WINDOWS_OVERLAPPED_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/push_options.hpp"
+
+#include "asio/io_service.hpp"
+#include "asio/detail/noncopyable.hpp"
+#include "asio/detail/win_iocp_overlapped_ptr.hpp"
+
+#if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+# if defined(ASIO_HAS_IOCP)
+#  define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1
+# endif // defined(ASIO_HAS_IOCP)
+#endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+
+#if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace asio {
+namespace windows {
+
+/// Wraps a handler to create an OVERLAPPED object for use with overlapped I/O.
+/**
+ * A special-purpose smart pointer used to wrap an application handler so that
+ * it can be passed as the LPOVERLAPPED argument to overlapped I/O functions.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: sa...@n
+ * @e Shared @e objects: Unsafe.
+ */
+class overlapped_ptr
+  : private noncopyable
+{
+public:
+  /// Construct an empty overlapped_ptr.
+  overlapped_ptr()
+    : impl_()
+  {
+  }
+
+  /// Construct an overlapped_ptr to contain the specified handler.
+  template <typename Handler>
+  explicit overlapped_ptr(asio::io_service& io_service, Handler handler)
+    : impl_(io_service, handler)
+  {
+  }
+
+  /// Destructor automatically frees the OVERLAPPED object unless released.
+  ~overlapped_ptr()
+  {
+  }
+
+  /// Reset to empty.
+  void reset()
+  {
+    impl_.reset();
+  }
+
+  /// Reset to contain the specified handler, freeing any current OVERLAPPED
+  /// object.
+  template <typename Handler>
+  void reset(asio::io_service& io_service, Handler handler)
+  {
+    impl_.reset(io_service, handler);
+  }
+
+  /// Get the contained OVERLAPPED object.
+  OVERLAPPED* get()
+  {
+    return impl_.get();
+  }
+
+  /// Get the contained OVERLAPPED object.
+  const OVERLAPPED* get() const
+  {
+    return impl_.get();
+  }
+
+  /// Release ownership of the OVERLAPPED object.
+  OVERLAPPED* release()
+  {
+    return impl_.release();
+  }
+
+  /// Post completion notification for overlapped operation. Releases 
ownership.
+  void complete(const asio::error_code& ec,
+      std::size_t bytes_transferred)
+  {
+    impl_.complete(ec, bytes_transferred);
+  }
+
+private:
+  detail::win_iocp_overlapped_ptr impl_;
+};
+
+} // namespace windows
+} // namespace asio
+
+#endif // defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_WINDOWS_OVERLAPPED_PTR_HPP



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"deluge-commit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/deluge-commit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to