Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84877 - in trunk/boost/asio/detail: . impl
From: chris_at_[hidden]
Date: 2013-06-22 08:47:44


Author: chris_kohlhoff
Date: 2013-06-22 08:47:44 EDT (Sat, 22 Jun 2013)
New Revision: 84877
URL: http://svn.boost.org/trac/boost/changeset/84877

Log:
Add mechanism for disabling automatic Winsock initialisation. Refs #3605

Text files modified:
   trunk/boost/asio/detail/impl/winsock_init.ipp | 13 +++++++++++++
   trunk/boost/asio/detail/winsock_init.hpp | 38 ++++++++++++++++++++++++++++++++++++++
   2 files changed, 51 insertions(+), 0 deletions(-)

Modified: trunk/boost/asio/detail/impl/winsock_init.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/winsock_init.ipp Sat Jun 22 08:45:33 2013 (r84876)
+++ trunk/boost/asio/detail/impl/winsock_init.ipp 2013-06-22 08:47:44 EDT (Sat, 22 Jun 2013) (r84877)
@@ -41,6 +41,14 @@
   }
 }
 
+void winsock_init_base::manual_startup(data& d)
+{
+ if (::InterlockedIncrement(&d.init_count_) == 1)
+ {
+ ::InterlockedExchange(&d.result_, 0);
+ }
+}
+
 void winsock_init_base::cleanup(data& d)
 {
   if (::InterlockedDecrement(&d.init_count_) == 0)
@@ -49,6 +57,11 @@
   }
 }
 
+void winsock_init_base::manual_cleanup(data& d)
+{
+ ::InterlockedDecrement(&d.init_count_);
+}
+
 void winsock_init_base::throw_on_error(data& d)
 {
   long result = ::InterlockedExchangeAdd(&d.result_, 0);

Modified: trunk/boost/asio/detail/winsock_init.hpp
==============================================================================
--- trunk/boost/asio/detail/winsock_init.hpp Sat Jun 22 08:45:33 2013 (r84876)
+++ trunk/boost/asio/detail/winsock_init.hpp 2013-06-22 08:47:44 EDT (Sat, 22 Jun 2013) (r84877)
@@ -39,8 +39,12 @@
   BOOST_ASIO_DECL static void startup(data& d,
       unsigned char major, unsigned char minor);
 
+ BOOST_ASIO_DECL static void manual_startup(data& d);
+
   BOOST_ASIO_DECL static void cleanup(data& d);
 
+ BOOST_ASIO_DECL static void manual_cleanup(data& d);
+
   BOOST_ASIO_DECL static void throw_on_error(data& d);
 };
 
@@ -66,7 +70,41 @@
     cleanup(data_);
   }
 
+ // This class may be used to indicate that user code will manage Winsock
+ // initialisation and cleanup. This may be required in the case of a DLL, for
+ // example, where it is not safe to initialise Winsock from global object
+ // constructors.
+ //
+ // To prevent asio from initialising Winsock, the object must be constructed
+ // before any Asio's own global objects. With MSVC, this may be accomplished
+ // by adding the following code to the DLL:
+ //
+ // #pragma warning(push)
+ // #pragma warning(disable:4073)
+ // #pragma init_seg(lib)
+ // boost::asio::detail::winsock_init<>::manual manual_winsock_init;
+ // #pragma warning(pop)
+ class manual
+ {
+ public:
+ manual()
+ {
+ manual_startup(data_);
+ }
+
+ manual(const manual&)
+ {
+ manual_startup(data_);
+ }
+
+ ~manual()
+ {
+ manual_cleanup(data_);
+ }
+ };
+
 private:
+ friend class manual;
   static data data_;
 };
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk