$search
00001 // 00002 // winsock_init.hpp 00003 // ~~~~~~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 00011 #ifndef ASIO_DETAIL_WINSOCK_INIT_HPP 00012 #define ASIO_DETAIL_WINSOCK_INIT_HPP 00013 00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 00015 # pragma once 00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 00017 00018 #include "asio/detail/push_options.hpp" 00019 00020 #include "asio/detail/push_options.hpp" 00021 #include <boost/config.hpp> 00022 #include "asio/detail/pop_options.hpp" 00023 00024 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) 00025 00026 #include "asio/detail/push_options.hpp" 00027 #include <boost/shared_ptr.hpp> 00028 #include <boost/throw_exception.hpp> 00029 #include "asio/detail/pop_options.hpp" 00030 00031 #include "asio/error.hpp" 00032 #include "asio/system_error.hpp" 00033 #include "asio/detail/noncopyable.hpp" 00034 #include "asio/detail/socket_types.hpp" 00035 00036 namespace asio { 00037 namespace detail { 00038 00039 template <int Major = 2, int Minor = 0> 00040 class winsock_init 00041 : private noncopyable 00042 { 00043 private: 00044 // Structure to perform the actual initialisation. 00045 struct do_init 00046 { 00047 do_init() 00048 { 00049 WSADATA wsa_data; 00050 result_ = ::WSAStartup(MAKEWORD(Major, Minor), &wsa_data); 00051 } 00052 00053 ~do_init() 00054 { 00055 ::WSACleanup(); 00056 } 00057 00058 int result() const 00059 { 00060 return result_; 00061 } 00062 00063 // Helper function to manage a do_init singleton. The static instance of the 00064 // winsock_init object ensures that this function is always called before 00065 // main, and therefore before any other threads can get started. The do_init 00066 // instance must be static in this function to ensure that it gets 00067 // initialised before any other global objects try to use it. 00068 static boost::shared_ptr<do_init> instance() 00069 { 00070 static boost::shared_ptr<do_init> init(new do_init); 00071 return init; 00072 } 00073 00074 private: 00075 int result_; 00076 }; 00077 00078 public: 00079 // Constructor. 00080 winsock_init() 00081 : ref_(do_init::instance()) 00082 { 00083 // Check whether winsock was successfully initialised. This check is not 00084 // performed for the global instance since there will be nobody around to 00085 // catch the exception. 00086 if (this != &instance_ && ref_->result() != 0) 00087 { 00088 asio::system_error e( 00089 asio::error_code(ref_->result(), 00090 asio::error::get_system_category()), 00091 "winsock"); 00092 boost::throw_exception(e); 00093 } 00094 } 00095 00096 // Destructor. 00097 ~winsock_init() 00098 { 00099 } 00100 00101 private: 00102 // Instance to force initialisation of winsock at global scope. 00103 static winsock_init instance_; 00104 00105 // Reference to singleton do_init object to ensure that winsock does not get 00106 // cleaned up until the last user has finished with it. 00107 boost::shared_ptr<do_init> ref_; 00108 }; 00109 00110 template <int Major, int Minor> 00111 winsock_init<Major, Minor> winsock_init<Major, Minor>::instance_; 00112 00113 } // namespace detail 00114 } // namespace asio 00115 00116 #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__) 00117 00118 #include "asio/detail/pop_options.hpp" 00119 00120 #endif // ASIO_DETAIL_WINSOCK_INIT_HPP