Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // detail/winsock_init.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_WINSOCK_INIT_HPP
0012 #define BOOST_ASIO_DETAIL_WINSOCK_INIT_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 
0020 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0021 
0022 #include <boost/asio/detail/push_options.hpp>
0023 
0024 namespace boost {
0025 namespace asio {
0026 namespace detail {
0027 
0028 class winsock_init_base
0029 {
0030 protected:
0031   // Structure to track result of initialisation and number of uses. POD is used
0032   // to ensure that the values are zero-initialised prior to any code being run.
0033   struct data
0034   {
0035     long init_count_;
0036     long result_;
0037   };
0038 
0039   BOOST_ASIO_DECL static void startup(data& d,
0040       unsigned char major, unsigned char minor);
0041 
0042   BOOST_ASIO_DECL static void manual_startup(data& d);
0043 
0044   BOOST_ASIO_DECL static void cleanup(data& d);
0045 
0046   BOOST_ASIO_DECL static void manual_cleanup(data& d);
0047 
0048   BOOST_ASIO_DECL static void throw_on_error(data& d);
0049 };
0050 
0051 template <int Major = 2, int Minor = 0>
0052 class winsock_init : private winsock_init_base
0053 {
0054 public:
0055   winsock_init(bool allow_throw = true)
0056   {
0057     startup(data_, Major, Minor);
0058     if (allow_throw)
0059       throw_on_error(data_);
0060   }
0061 
0062   winsock_init(const winsock_init&)
0063   {
0064     startup(data_, Major, Minor);
0065     throw_on_error(data_);
0066   }
0067 
0068   ~winsock_init()
0069   {
0070     cleanup(data_);
0071   }
0072 
0073   // This class may be used to indicate that user code will manage Winsock
0074   // initialisation and cleanup. This may be required in the case of a DLL, for
0075   // example, where it is not safe to initialise Winsock from global object
0076   // constructors.
0077   //
0078   // To prevent asio from initialising Winsock, the object must be constructed
0079   // before any Asio's own global objects. With MSVC, this may be accomplished
0080   // by adding the following code to the DLL:
0081   //
0082   //   #pragma warning(push)
0083   //   #pragma warning(disable:4073)
0084   //   #pragma init_seg(lib)
0085   //   boost::asio::detail::winsock_init<>::manual manual_winsock_init;
0086   //   #pragma warning(pop)
0087   class manual
0088   {
0089   public:
0090     manual()
0091     {
0092       manual_startup(data_);
0093     }
0094 
0095     manual(const manual&)
0096     {
0097       manual_startup(data_);
0098     }
0099 
0100     ~manual()
0101     {
0102       manual_cleanup(data_);
0103     }
0104   };
0105 
0106 private:
0107   friend class manual;
0108   static data data_;
0109 };
0110 
0111 template <int Major, int Minor>
0112 winsock_init_base::data winsock_init<Major, Minor>::data_;
0113 
0114 // Static variable to ensure that winsock is initialised before main, and
0115 // therefore before any other threads can get started.
0116 static const winsock_init<>& winsock_init_instance = winsock_init<>(false);
0117 
0118 } // namespace detail
0119 } // namespace asio
0120 } // namespace boost
0121 
0122 #include <boost/asio/detail/pop_options.hpp>
0123 
0124 #if defined(BOOST_ASIO_HEADER_ONLY)
0125 # include <boost/asio/detail/impl/winsock_init.ipp>
0126 #endif // defined(BOOST_ASIO_HEADER_ONLY)
0127 
0128 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0129 
0130 #endif // BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP