Chris@16: // Chris@16: // detail/winsock_init.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP Chris@16: #define BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: class winsock_init_base Chris@16: { Chris@16: protected: Chris@16: // Structure to track result of initialisation and number of uses. POD is used Chris@16: // to ensure that the values are zero-initialised prior to any code being run. Chris@16: struct data Chris@16: { Chris@16: long init_count_; Chris@16: long result_; Chris@16: }; Chris@16: Chris@16: BOOST_ASIO_DECL static void startup(data& d, Chris@16: unsigned char major, unsigned char minor); Chris@16: Chris@16: BOOST_ASIO_DECL static void manual_startup(data& d); Chris@16: Chris@16: BOOST_ASIO_DECL static void cleanup(data& d); Chris@16: Chris@16: BOOST_ASIO_DECL static void manual_cleanup(data& d); Chris@16: Chris@16: BOOST_ASIO_DECL static void throw_on_error(data& d); Chris@16: }; Chris@16: Chris@16: template Chris@16: class winsock_init : private winsock_init_base Chris@16: { Chris@16: public: Chris@16: winsock_init(bool allow_throw = true) Chris@16: { Chris@16: startup(data_, Major, Minor); Chris@16: if (allow_throw) Chris@16: throw_on_error(data_); Chris@16: } Chris@16: Chris@16: winsock_init(const winsock_init&) Chris@16: { Chris@16: startup(data_, Major, Minor); Chris@16: throw_on_error(data_); Chris@16: } Chris@16: Chris@16: ~winsock_init() Chris@16: { Chris@16: cleanup(data_); Chris@16: } Chris@16: Chris@16: // This class may be used to indicate that user code will manage Winsock Chris@16: // initialisation and cleanup. This may be required in the case of a DLL, for Chris@16: // example, where it is not safe to initialise Winsock from global object Chris@16: // constructors. Chris@16: // Chris@16: // To prevent asio from initialising Winsock, the object must be constructed Chris@16: // before any Asio's own global objects. With MSVC, this may be accomplished Chris@16: // by adding the following code to the DLL: Chris@16: // Chris@16: // #pragma warning(push) Chris@16: // #pragma warning(disable:4073) Chris@16: // #pragma init_seg(lib) Chris@16: // boost::asio::detail::winsock_init<>::manual manual_winsock_init; Chris@16: // #pragma warning(pop) Chris@16: class manual Chris@16: { Chris@16: public: Chris@16: manual() Chris@16: { Chris@16: manual_startup(data_); Chris@16: } Chris@16: Chris@16: manual(const manual&) Chris@16: { Chris@16: manual_startup(data_); Chris@16: } Chris@16: Chris@16: ~manual() Chris@16: { Chris@16: manual_cleanup(data_); Chris@16: } Chris@16: }; Chris@16: Chris@16: private: Chris@16: friend class manual; Chris@16: static data data_; Chris@16: }; Chris@16: Chris@16: template Chris@16: winsock_init_base::data winsock_init::data_; Chris@16: Chris@16: // Static variable to ensure that winsock is initialised before main, and Chris@16: // therefore before any other threads can get started. Chris@16: static const winsock_init<>& winsock_init_instance = winsock_init<>(false); Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_ASIO_HEADER_ONLY) Chris@16: # include Chris@16: #endif // defined(BOOST_ASIO_HEADER_ONLY) Chris@16: Chris@16: #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP