Changeset 44673


Ignore:
Timestamp:
Apr 21, 2008, 4:02:37 AM (10 years ago)
Author:
chris_kohlhoff
Message:

Add a special null_buffers type that allows read and write operations to
be used to indicate the socket's readiness to read or write without
blocking.

Location:
trunk
Files:
4 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/boost/asio/buffer.hpp

    r43472 r44673  
    378378    return begin() + 1;
    379379  }
     380};
     381
     382/// An implementation of both the ConstBufferSequence and MutableBufferSequence
     383/// concepts to represent a null buffer sequence.
     384class null_buffers
     385{
     386public:
     387  /// The type for each element in the list of buffers.
     388  typedef mutable_buffer value_type;
     389
     390  /// A random-access iterator type that may be used to read elements.
     391  typedef const mutable_buffer* const_iterator;
     392
     393  /// Get a random-access iterator to the first element.
     394  const_iterator begin() const
     395  {
     396    return &buf_;
     397  }
     398
     399  /// Get a random-access iterator for one past the last element.
     400  const_iterator end() const
     401  {
     402    return &buf_;
     403  }
     404
     405private:
     406  mutable_buffer buf_;
    380407};
    381408
  • trunk/boost/asio/detail/consuming_buffers.hpp

    r43472 r44673  
    2424#include <boost/iterator/iterator_facade.hpp>
    2525#include <boost/asio/detail/pop_options.hpp>
     26
     27#include <boost/asio/buffer.hpp>
    2628
    2729namespace boost {
     
    199201};
    200202
     203// Specialisation for null_buffers to ensure that the null_buffers type is
     204// always passed through to the underlying read or write operation.
     205template <typename Buffer>
     206class consuming_buffers<Buffer, boost::asio::null_buffers>
     207  : public boost::asio::null_buffers
     208{
     209public:
     210  consuming_buffers(const boost::asio::null_buffers&)
     211  {
     212    // No-op.
     213  }
     214
     215  void consume(std::size_t)
     216  {
     217    // No-op.
     218  }
     219};
     220
    201221} // namespace detail
    202222} // namespace asio
  • trunk/boost/asio/detail/dev_poll_reactor.hpp

    r43472 r44673  
    129129  // given descriptor is ready to be read, or an error has occurred.
    130130  template <typename Handler>
    131   void start_read_op(socket_type descriptor, Handler handler)
     131  void start_read_op(socket_type descriptor, Handler handler,
     132      bool allow_speculative_read = true)
    132133  {
    133134    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    136137      return;
    137138
    138     if (!read_op_queue_.has_operation(descriptor))
    139       if (handler(boost::system::error_code()))
    140         return;
     139    if (allow_speculative_read)
     140      if (!read_op_queue_.has_operation(descriptor))
     141        if (handler(boost::system::error_code()))
     142          return;
    141143
    142144    if (read_op_queue_.enqueue_operation(descriptor, handler))
     
    155157  // given descriptor is ready to be written, or an error has occurred.
    156158  template <typename Handler>
    157   void start_write_op(socket_type descriptor, Handler handler)
     159  void start_write_op(socket_type descriptor, Handler handler,
     160      bool allow_speculative_write = true)
    158161  {
    159162    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    162165      return;
    163166
    164     if (!write_op_queue_.has_operation(descriptor))
    165       if (handler(boost::system::error_code()))
    166         return;
     167    if (allow_speculative_write)
     168      if (!write_op_queue_.has_operation(descriptor))
     169        if (handler(boost::system::error_code()))
     170          return;
    167171
    168172    if (write_op_queue_.enqueue_operation(descriptor, handler))
  • trunk/boost/asio/detail/epoll_reactor.hpp

    r43472 r44673  
    136136  // given descriptor is ready to be read, or an error has occurred.
    137137  template <typename Handler>
    138   void start_read_op(socket_type descriptor, Handler handler)
     138  void start_read_op(socket_type descriptor, Handler handler,
     139      bool allow_speculative_read = true)
    139140  {
    140141    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    143144      return;
    144145
    145     if (!read_op_queue_.has_operation(descriptor))
     146    if (!allow_speculative_read)
     147      need_epoll_wait_ = true;
     148    else if (!read_op_queue_.has_operation(descriptor))
    146149      if (handler(boost::system::error_code()))
    147150        return;
     
    172175  // given descriptor is ready to be written, or an error has occurred.
    173176  template <typename Handler>
    174   void start_write_op(socket_type descriptor, Handler handler)
     177  void start_write_op(socket_type descriptor, Handler handler,
     178      bool allow_speculative_write = true)
    175179  {
    176180    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    179183      return;
    180184
    181     if (!write_op_queue_.has_operation(descriptor))
     185    if (!allow_speculative_write)
     186      need_epoll_wait_ = true;
     187    else if (!write_op_queue_.has_operation(descriptor))
    182188      if (handler(boost::system::error_code()))
    183189        return;
  • trunk/boost/asio/detail/kqueue_reactor.hpp

    r43472 r44673  
    136136  // given descriptor is ready to be read, or an error has occurred.
    137137  template <typename Handler>
    138   void start_read_op(socket_type descriptor, Handler handler)
     138  void start_read_op(socket_type descriptor, Handler handler,
     139      bool allow_speculative_read = true)
    139140  {
    140141    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    143144      return;
    144145
    145     if (!read_op_queue_.has_operation(descriptor))
     146    if (!allow_speculative_read)
     147      need_kqueue_wait_ = true;
     148    else if (!read_op_queue_.has_operation(descriptor))
    146149      if (handler(boost::system::error_code()))
    147150        return;
     
    163166  // given descriptor is ready to be written, or an error has occurred.
    164167  template <typename Handler>
    165   void start_write_op(socket_type descriptor, Handler handler)
     168  void start_write_op(socket_type descriptor, Handler handler,
     169      bool allow_speculative_write = true)
    166170  {
    167171    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    170174      return;
    171175
    172     if (!write_op_queue_.has_operation(descriptor))
     176    if (!allow_speculative_write)
     177      need_kqueue_wait_ = true;
     178    else if (!write_op_queue_.has_operation(descriptor))
    173179      if (handler(boost::system::error_code()))
    174180        return;
  • trunk/boost/asio/detail/reactive_socket_service.hpp

    r43472 r44673  
    560560  }
    561561
     562  // Wait until data can be sent without blocking.
     563  size_t send(implementation_type& impl, const null_buffers&,
     564      socket_base::message_flags, boost::system::error_code& ec)
     565  {
     566    if (!is_open(impl))
     567    {
     568      ec = boost::asio::error::bad_descriptor;
     569      return 0;
     570    }
     571
     572    // Wait for socket to become ready.
     573    socket_ops::poll_write(impl.socket_, ec);
     574
     575    return 0;
     576  }
     577
    562578  template <typename ConstBufferSequence, typename Handler>
    563579  class send_handler
     
    674690  }
    675691
     692  template <typename Handler>
     693  class null_buffers_handler
     694  {
     695  public:
     696    null_buffers_handler(boost::asio::io_service& io_service, Handler handler)
     697      : work_(io_service),
     698        handler_(handler)
     699    {
     700    }
     701
     702    bool operator()(const boost::system::error_code& result)
     703    {
     704      work_.get_io_service().post(bind_handler(handler_, result, 0));
     705      return true;
     706    }
     707
     708  private:
     709    boost::asio::io_service::work work_;
     710    Handler handler_;
     711  };
     712
     713  // Start an asynchronous wait until data can be sent without blocking.
     714  template <typename Handler>
     715  void async_send(implementation_type& impl, const null_buffers&,
     716      socket_base::message_flags, Handler handler)
     717  {
     718    if (!is_open(impl))
     719    {
     720      this->get_io_service().post(bind_handler(handler,
     721            boost::asio::error::bad_descriptor, 0));
     722    }
     723    else
     724    {
     725      reactor_.start_write_op(impl.socket_,
     726          null_buffers_handler<Handler>(this->get_io_service(), handler),
     727          false);
     728    }
     729  }
     730
    676731  // Send a datagram to the specified endpoint. Returns the number of bytes
    677732  // sent.
     
    733788        return 0;
    734789    }
     790  }
     791
     792  // Wait until data can be sent without blocking.
     793  size_t send_to(implementation_type& impl, const null_buffers&,
     794      socket_base::message_flags, const endpoint_type&,
     795      boost::system::error_code& ec)
     796  {
     797    if (!is_open(impl))
     798    {
     799      ec = boost::asio::error::bad_descriptor;
     800      return 0;
     801    }
     802
     803    // Wait for socket to become ready.
     804    socket_ops::poll_write(impl.socket_, ec);
     805
     806    return 0;
    735807  }
    736808
     
    833905  }
    834906
     907  // Start an asynchronous wait until data can be sent without blocking.
     908  template <typename Handler>
     909  void async_send_to(implementation_type& impl, const null_buffers&,
     910      socket_base::message_flags, const endpoint_type&, Handler handler)
     911  {
     912    if (!is_open(impl))
     913    {
     914      this->get_io_service().post(bind_handler(handler,
     915            boost::asio::error::bad_descriptor, 0));
     916    }
     917    else
     918    {
     919      reactor_.start_write_op(impl.socket_,
     920          null_buffers_handler<Handler>(this->get_io_service(), handler),
     921          false);
     922    }
     923  }
     924
    835925  // Receive some data from the peer. Returns the number of bytes received.
    836926  template <typename MutableBufferSequence>
     
    906996        return 0;
    907997    }
     998  }
     999
     1000  // Wait until data can be received without blocking.
     1001  size_t receive(implementation_type& impl,
     1002      const null_buffers& buffers,
     1003      socket_base::message_flags, boost::system::error_code& ec)
     1004  {
     1005    if (!is_open(impl))
     1006    {
     1007      ec = boost::asio::error::bad_descriptor;
     1008      return 0;
     1009    }
     1010
     1011    // Wait for socket to become ready.
     1012    socket_ops::poll_read(impl.socket_, ec);
     1013
     1014    return 0;
    9081015  }
    9091016
     
    10341141  }
    10351142
     1143  // Wait until data can be received without blocking.
     1144  template <typename Handler>
     1145  void async_receive(implementation_type& impl, const null_buffers&,
     1146      socket_base::message_flags flags, Handler handler)
     1147  {
     1148    if (!is_open(impl))
     1149    {
     1150      this->get_io_service().post(bind_handler(handler,
     1151            boost::asio::error::bad_descriptor, 0));
     1152    }
     1153    else if (flags & socket_base::message_out_of_band)
     1154    {
     1155      reactor_.start_except_op(impl.socket_,
     1156          null_buffers_handler<Handler>(this->get_io_service(), handler));
     1157    }
     1158    else
     1159    {
     1160      reactor_.start_read_op(impl.socket_,
     1161          null_buffers_handler<Handler>(this->get_io_service(), handler),
     1162          false);
     1163    }
     1164  }
     1165
    10361166  // Receive a datagram with the endpoint of the sender. Returns the number of
    10371167  // bytes received.
     
    11051235        return 0;
    11061236    }
     1237  }
     1238
     1239  // Wait until data can be received without blocking.
     1240  size_t receive_from(implementation_type& impl,
     1241      const null_buffers& buffers, endpoint_type& sender_endpoint,
     1242      socket_base::message_flags, boost::system::error_code& ec)
     1243  {
     1244    if (!is_open(impl))
     1245    {
     1246      ec = boost::asio::error::bad_descriptor;
     1247      return 0;
     1248    }
     1249
     1250    // Wait for socket to become ready.
     1251    socket_ops::poll_read(impl.socket_, ec);
     1252
     1253    // Reset endpoint since it can be given no sensible value at this time.
     1254    sender_endpoint = endpoint_type();
     1255
     1256    return 0;
    11071257  }
    11081258
     
    12071357            impl.socket_, this->get_io_service(), buffers,
    12081358            sender_endpoint, flags, handler));
     1359    }
     1360  }
     1361
     1362  // Wait until data can be received without blocking.
     1363  template <typename Handler>
     1364  void async_receive_from(implementation_type& impl,
     1365      const null_buffers&, endpoint_type& sender_endpoint,
     1366      socket_base::message_flags flags, Handler handler)
     1367  {
     1368    if (!is_open(impl))
     1369    {
     1370      this->get_io_service().post(bind_handler(handler,
     1371            boost::asio::error::bad_descriptor, 0));
     1372    }
     1373    else
     1374    {
     1375      // Reset endpoint since it can be given no sensible value at this time.
     1376      sender_endpoint = endpoint_type();
     1377
     1378      if (flags & socket_base::message_out_of_band)
     1379      {
     1380        reactor_.start_except_op(impl.socket_,
     1381            null_buffers_handler<Handler>(this->get_io_service(), handler));
     1382      }
     1383      else
     1384      {
     1385        reactor_.start_read_op(impl.socket_,
     1386            null_buffers_handler<Handler>(this->get_io_service(), handler),
     1387            false);
     1388      }
    12091389    }
    12101390  }
  • trunk/boost/asio/detail/select_reactor.hpp

    r43472 r44673  
    116116  // given descriptor is ready to be read, or an error has occurred.
    117117  template <typename Handler>
    118   void start_read_op(socket_type descriptor, Handler handler)
     118  void start_read_op(socket_type descriptor, Handler handler,
     119      bool /*allow_speculative_read*/ = true)
    119120  {
    120121    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     
    127128  // given descriptor is ready to be written, or an error has occurred.
    128129  template <typename Handler>
    129   void start_write_op(socket_type descriptor, Handler handler)
     130  void start_write_op(socket_type descriptor, Handler handler,
     131      bool /*allow_speculative_write*/ = true)
    130132  {
    131133    boost::asio::detail::mutex::scoped_lock lock(mutex_);
  • trunk/boost/asio/detail/win_iocp_socket_service.hpp

    r43472 r44673  
    2525#include <cstring>
    2626#include <boost/shared_ptr.hpp>
     27#include <boost/type_traits/is_same.hpp>
    2728#include <boost/weak_ptr.hpp>
    2829#include <boost/asio/detail/pop_options.hpp>
     
    701702  }
    702703
     704  // Wait until data can be sent without blocking.
     705  size_t send(implementation_type& impl, const null_buffers&,
     706      socket_base::message_flags, boost::system::error_code& ec)
     707  {
     708    if (!is_open(impl))
     709    {
     710      ec = boost::asio::error::bad_descriptor;
     711      return 0;
     712    }
     713
     714    // Wait for socket to become ready.
     715    socket_ops::poll_write(impl.socket_, ec);
     716
     717    return 0;
     718  }
     719
    703720  template <typename ConstBufferSequence, typename Handler>
    704721  class send_operation
     
    859876  }
    860877
     878  template <typename Handler>
     879  class null_buffers_handler
     880  {
     881  public:
     882    null_buffers_handler(boost::asio::io_service& io_service, Handler handler)
     883      : work_(io_service),
     884        handler_(handler)
     885    {
     886    }
     887
     888    bool operator()(const boost::system::error_code& result)
     889    {
     890      work_.get_io_service().post(bind_handler(handler_, result, 0));
     891      return true;
     892    }
     893
     894  private:
     895    boost::asio::io_service::work work_;
     896    Handler handler_;
     897  };
     898
     899  // Start an asynchronous wait until data can be sent without blocking.
     900  template <typename Handler>
     901  void async_send(implementation_type& impl, const null_buffers&,
     902      socket_base::message_flags, Handler handler)
     903  {
     904    if (!is_open(impl))
     905    {
     906      this->get_io_service().post(bind_handler(handler,
     907            boost::asio::error::bad_descriptor, 0));
     908    }
     909    else
     910    {
     911      // Check if the reactor was already obtained from the io_service.
     912      reactor_type* reactor = static_cast<reactor_type*>(
     913            interlocked_compare_exchange_pointer(
     914              reinterpret_cast<void**>(&reactor_), 0, 0));
     915      if (!reactor)
     916      {
     917        reactor = &(boost::asio::use_service<reactor_type>(
     918              this->get_io_service()));
     919        interlocked_exchange_pointer(
     920            reinterpret_cast<void**>(&reactor_), reactor);
     921      }
     922
     923      reactor->start_write_op(impl.socket_,
     924          null_buffers_handler<Handler>(this->get_io_service(), handler),
     925          false);
     926    }
     927  }
     928
    861929  // Send a datagram to the specified endpoint. Returns the number of bytes
    862930  // sent.
     
    901969    ec = boost::system::error_code();
    902970    return bytes_transferred;
     971  }
     972
     973  // Wait until data can be sent without blocking.
     974  size_t send_to(implementation_type& impl, const null_buffers&,
     975      socket_base::message_flags, const endpoint_type&,
     976      boost::system::error_code& ec)
     977  {
     978    if (!is_open(impl))
     979    {
     980      ec = boost::asio::error::bad_descriptor;
     981      return 0;
     982    }
     983
     984    // Wait for socket to become ready.
     985    socket_ops::poll_write(impl.socket_, ec);
     986
     987    return 0;
    903988  }
    904989
     
    10391124  }
    10401125
     1126  // Start an asynchronous wait until data can be sent without blocking.
     1127  template <typename Handler>
     1128  void async_send_to(implementation_type& impl, const null_buffers&,
     1129      socket_base::message_flags, const endpoint_type&, Handler handler)
     1130  {
     1131    if (!is_open(impl))
     1132    {
     1133      this->get_io_service().post(bind_handler(handler,
     1134            boost::asio::error::bad_descriptor, 0));
     1135    }
     1136    else
     1137    {
     1138      // Check if the reactor was already obtained from the io_service.
     1139      reactor_type* reactor = static_cast<reactor_type*>(
     1140            interlocked_compare_exchange_pointer(
     1141              reinterpret_cast<void**>(&reactor_), 0, 0));
     1142      if (!reactor)
     1143      {
     1144        reactor = &(boost::asio::use_service<reactor_type>(
     1145              this->get_io_service()));
     1146        interlocked_exchange_pointer(
     1147            reinterpret_cast<void**>(&reactor_), reactor);
     1148      }
     1149
     1150      reactor->start_write_op(impl.socket_,
     1151          null_buffers_handler<Handler>(this->get_io_service(), handler),
     1152          false);
     1153    }
     1154  }
     1155
    10411156  // Receive some data from the peer. Returns the number of bytes received.
    10421157  template <typename MutableBufferSequence>
     
    10961211    ec = boost::system::error_code();
    10971212    return bytes_transferred;
     1213  }
     1214
     1215  // Wait until data can be received without blocking.
     1216  size_t receive(implementation_type& impl,
     1217      const null_buffers& buffers,
     1218      socket_base::message_flags, boost::system::error_code& ec)
     1219  {
     1220    if (!is_open(impl))
     1221    {
     1222      ec = boost::asio::error::bad_descriptor;
     1223      return 0;
     1224    }
     1225
     1226    // Wait for socket to become ready.
     1227    socket_ops::poll_read(impl.socket_, ec);
     1228
     1229    return 0;
    10981230  }
    10991231
     
    11581290
    11591291      // Check for connection closed.
    1160       else if (!ec && bytes_transferred == 0)
     1292      else if (!ec && bytes_transferred == 0
     1293          && !boost::is_same<MutableBufferSequence, null_buffers>::value)
    11611294      {
    11621295        ec = boost::asio::error::eof;
     
    12631396  }
    12641397
     1398  // Wait until data can be received without blocking.
     1399  template <typename Handler>
     1400  void async_receive(implementation_type& impl, const null_buffers& buffers,
     1401      socket_base::message_flags flags, Handler handler)
     1402  {
     1403    if (!is_open(impl))
     1404    {
     1405      this->get_io_service().post(bind_handler(handler,
     1406            boost::asio::error::bad_descriptor, 0));
     1407    }
     1408    else if (impl.protocol_.type() == SOCK_STREAM)
     1409    {
     1410      // For stream sockets on Windows, we may issue a 0-byte overlapped
     1411      // WSARecv to wait until there is data available on the socket.
     1412
     1413#if defined(BOOST_ASIO_ENABLE_CANCELIO)
     1414      // Update the ID of the thread from which cancellation is safe.
     1415      if (impl.safe_cancellation_thread_id_ == 0)
     1416        impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
     1417      else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
     1418        impl.safe_cancellation_thread_id_ = ~DWORD(0);
     1419#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
     1420
     1421      // Allocate and construct an operation to wrap the handler.
     1422      typedef receive_operation<null_buffers, Handler> value_type;
     1423      typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     1424      raw_handler_ptr<alloc_traits> raw_ptr(handler);
     1425      handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_,
     1426          impl.cancel_token_, buffers, handler);
     1427
     1428      // Issue a receive operation with an empty buffer.
     1429      ::WSABUF buf = { 0, 0 };
     1430      DWORD bytes_transferred = 0;
     1431      DWORD recv_flags = flags;
     1432      int result = ::WSARecv(impl.socket_, &buf, 1,
     1433          &bytes_transferred, &recv_flags, ptr.get(), 0);
     1434      DWORD last_error = ::WSAGetLastError();
     1435      if (result != 0 && last_error != WSA_IO_PENDING)
     1436      {
     1437        boost::asio::io_service::work work(this->get_io_service());
     1438        ptr.reset();
     1439        boost::system::error_code ec(last_error,
     1440            boost::asio::error::get_system_category());
     1441        iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
     1442      }
     1443      else
     1444      {
     1445        ptr.release();
     1446      }
     1447    }
     1448    else
     1449    {
     1450      // Check if the reactor was already obtained from the io_service.
     1451      reactor_type* reactor = static_cast<reactor_type*>(
     1452            interlocked_compare_exchange_pointer(
     1453              reinterpret_cast<void**>(&reactor_), 0, 0));
     1454      if (!reactor)
     1455      {
     1456        reactor = &(boost::asio::use_service<reactor_type>(
     1457              this->get_io_service()));
     1458        interlocked_exchange_pointer(
     1459            reinterpret_cast<void**>(&reactor_), reactor);
     1460      }
     1461
     1462      if (flags & socket_base::message_out_of_band)
     1463      {
     1464        reactor->start_except_op(impl.socket_,
     1465            null_buffers_handler<Handler>(this->get_io_service(), handler));
     1466      }
     1467      else
     1468      {
     1469        reactor->start_read_op(impl.socket_,
     1470            null_buffers_handler<Handler>(this->get_io_service(), handler),
     1471            false);
     1472      }
     1473    }
     1474  }
     1475
    12651476  // Receive a datagram with the endpoint of the sender. Returns the number of
    12661477  // bytes received.
     
    13141525    ec = boost::system::error_code();
    13151526    return bytes_transferred;
     1527  }
     1528
     1529  // Wait until data can be received without blocking.
     1530  size_t receive_from(implementation_type& impl,
     1531      const null_buffers& buffers, endpoint_type& sender_endpoint,
     1532      socket_base::message_flags, boost::system::error_code& ec)
     1533  {
     1534    if (!is_open(impl))
     1535    {
     1536      ec = boost::asio::error::bad_descriptor;
     1537      return 0;
     1538    }
     1539
     1540    // Wait for socket to become ready.
     1541    socket_ops::poll_read(impl.socket_, ec);
     1542
     1543    // Reset endpoint since it can be given no sensible value at this time.
     1544    sender_endpoint = endpoint_type();
     1545
     1546    return 0;
    13161547  }
    13171548
     
    14711702    {
    14721703      ptr.release();
     1704    }
     1705  }
     1706
     1707  // Wait until data can be received without blocking.
     1708  template <typename Handler>
     1709  void async_receive_from(implementation_type& impl,
     1710      const null_buffers&, endpoint_type& sender_endpoint,
     1711      socket_base::message_flags flags, Handler handler)
     1712  {
     1713    if (!is_open(impl))
     1714    {
     1715      this->get_io_service().post(bind_handler(handler,
     1716            boost::asio::error::bad_descriptor, 0));
     1717    }
     1718    else
     1719    {
     1720      // Check if the reactor was already obtained from the io_service.
     1721      reactor_type* reactor = static_cast<reactor_type*>(
     1722            interlocked_compare_exchange_pointer(
     1723              reinterpret_cast<void**>(&reactor_), 0, 0));
     1724      if (!reactor)
     1725      {
     1726        reactor = &(boost::asio::use_service<reactor_type>(
     1727              this->get_io_service()));
     1728        interlocked_exchange_pointer(
     1729            reinterpret_cast<void**>(&reactor_), reactor);
     1730      }
     1731
     1732      // Reset endpoint since it can be given no sensible value at this time.
     1733      sender_endpoint = endpoint_type();
     1734
     1735      if (flags & socket_base::message_out_of_band)
     1736      {
     1737        reactor->start_except_op(impl.socket_,
     1738            null_buffers_handler<Handler>(this->get_io_service(), handler));
     1739      }
     1740      else
     1741      {
     1742        reactor->start_read_op(impl.socket_,
     1743            null_buffers_handler<Handler>(this->get_io_service(), handler),
     1744            false);
     1745      }
    14731746    }
    14741747  }
  • trunk/libs/asio/test/ip/tcp.cpp

    r43472 r44673  
    240240    socket1.send(buffer(mutable_char_buffer));
    241241    socket1.send(buffer(const_char_buffer));
     242    socket1.send(null_buffers());
    242243    socket1.send(buffer(mutable_char_buffer), in_flags);
    243244    socket1.send(buffer(const_char_buffer), in_flags);
     245    socket1.send(null_buffers(), in_flags);
    244246    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
    245247    socket1.send(buffer(const_char_buffer), in_flags, ec);
     248    socket1.send(null_buffers(), in_flags, ec);
    246249
    247250    socket1.async_send(buffer(mutable_char_buffer), send_handler);
    248251    socket1.async_send(buffer(const_char_buffer), send_handler);
     252    socket1.async_send(null_buffers(), send_handler);
    249253    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
    250254    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
     255    socket1.async_send(null_buffers(), in_flags, send_handler);
    251256
    252257    socket1.receive(buffer(mutable_char_buffer));
     258    socket1.receive(null_buffers());
    253259    socket1.receive(buffer(mutable_char_buffer), in_flags);
     260    socket1.receive(null_buffers(), in_flags);
    254261    socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
     262    socket1.receive(null_buffers(), in_flags, ec);
    255263
    256264    socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
     265    socket1.async_receive(null_buffers(), receive_handler);
    257266    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
    258267        receive_handler);
     268    socket1.async_receive(null_buffers(), in_flags, receive_handler);
    259269
    260270    socket1.write_some(buffer(mutable_char_buffer));
    261271    socket1.write_some(buffer(const_char_buffer));
     272    socket1.write_some(null_buffers());
    262273    socket1.write_some(buffer(mutable_char_buffer), ec);
    263274    socket1.write_some(buffer(const_char_buffer), ec);
     275    socket1.write_some(null_buffers(), ec);
    264276
    265277    socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
    266278    socket1.async_write_some(buffer(const_char_buffer), write_some_handler);
     279    socket1.async_write_some(null_buffers(), write_some_handler);
    267280
    268281    socket1.read_some(buffer(mutable_char_buffer));
    269282    socket1.read_some(buffer(mutable_char_buffer), ec);
     283    socket1.read_some(null_buffers(), ec);
    270284
    271285    socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
     286    socket1.async_read_some(null_buffers(), read_some_handler);
    272287  }
    273288  catch (std::exception&)
  • trunk/libs/asio/test/ip/udp.cpp

    r43472 r44673  
    145145    socket1.send(buffer(mutable_char_buffer));
    146146    socket1.send(buffer(const_char_buffer));
     147    socket1.send(null_buffers());
    147148    socket1.send(buffer(mutable_char_buffer), in_flags);
    148149    socket1.send(buffer(const_char_buffer), in_flags);
     150    socket1.send(null_buffers(), in_flags);
    149151    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
    150152    socket1.send(buffer(const_char_buffer), in_flags, ec);
     153    socket1.send(null_buffers(), in_flags, ec);
    151154
    152155    socket1.async_send(buffer(mutable_char_buffer), send_handler);
    153156    socket1.async_send(buffer(const_char_buffer), send_handler);
     157    socket1.async_send(null_buffers(), send_handler);
    154158    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
    155159    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
     160    socket1.async_send(null_buffers(), in_flags, send_handler);
    156161
    157162    socket1.send_to(buffer(mutable_char_buffer),
     
    163168    socket1.send_to(buffer(const_char_buffer),
    164169        ip::udp::endpoint(ip::udp::v6(), 0));
     170    socket1.send_to(null_buffers(),
     171        ip::udp::endpoint(ip::udp::v4(), 0));
     172    socket1.send_to(null_buffers(),
     173        ip::udp::endpoint(ip::udp::v6(), 0));
    165174    socket1.send_to(buffer(mutable_char_buffer),
    166175        ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
     
    171180    socket1.send_to(buffer(const_char_buffer),
    172181        ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
     182    socket1.send_to(null_buffers(),
     183        ip::udp::endpoint(ip::udp::v4(), 0), in_flags);
     184    socket1.send_to(null_buffers(),
     185        ip::udp::endpoint(ip::udp::v6(), 0), in_flags);
    173186    socket1.send_to(buffer(mutable_char_buffer),
    174187        ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
     
    178191        ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
    179192    socket1.send_to(buffer(const_char_buffer),
     193        ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
     194    socket1.send_to(null_buffers(),
     195        ip::udp::endpoint(ip::udp::v4(), 0), in_flags, ec);
     196    socket1.send_to(null_buffers(),
    180197        ip::udp::endpoint(ip::udp::v6(), 0), in_flags, ec);
    181198
     
    187204        ip::udp::endpoint(ip::udp::v4(), 0), send_handler);
    188205    socket1.async_send_to(buffer(const_char_buffer),
     206        ip::udp::endpoint(ip::udp::v6(), 0), send_handler);
     207    socket1.async_send_to(null_buffers(),
     208        ip::udp::endpoint(ip::udp::v4(), 0), send_handler);
     209    socket1.async_send_to(null_buffers(),
    189210        ip::udp::endpoint(ip::udp::v6(), 0), send_handler);
    190211    socket1.async_send_to(buffer(mutable_char_buffer),
     
    196217    socket1.async_send_to(buffer(const_char_buffer),
    197218        ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler);
     219    socket1.async_send_to(null_buffers(),
     220        ip::udp::endpoint(ip::udp::v4(), 0), in_flags, send_handler);
     221    socket1.async_send_to(null_buffers(),
     222        ip::udp::endpoint(ip::udp::v6(), 0), in_flags, send_handler);
    198223
    199224    socket1.receive(buffer(mutable_char_buffer));
     225    socket1.receive(null_buffers());
    200226    socket1.receive(buffer(mutable_char_buffer), in_flags);
     227    socket1.receive(null_buffers(), in_flags);
    201228    socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
     229    socket1.receive(null_buffers(), in_flags, ec);
    202230
    203231    socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
     232    socket1.async_receive(null_buffers(), receive_handler);
    204233    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
    205234        receive_handler);
     235    socket1.async_receive(null_buffers(), in_flags, receive_handler);
    206236
    207237    ip::udp::endpoint endpoint;
    208238    socket1.receive_from(buffer(mutable_char_buffer), endpoint);
     239    socket1.receive_from(null_buffers(), endpoint);
    209240    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
     241    socket1.receive_from(null_buffers(), endpoint, in_flags);
    210242    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
     243    socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
    211244
    212245    socket1.async_receive_from(buffer(mutable_char_buffer),
    213246        endpoint, receive_handler);
     247    socket1.async_receive_from(null_buffers(),
     248        endpoint, receive_handler);
    214249    socket1.async_receive_from(buffer(mutable_char_buffer),
     250        endpoint, in_flags, receive_handler);
     251    socket1.async_receive_from(null_buffers(),
    215252        endpoint, in_flags, receive_handler);
    216253  }
Note: See TracChangeset for help on using the changeset viewer.