1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <thrift/windows/TWinsockSingleton.h>
21 
22 // boost
23 #include <boost/assert.hpp>
24 #include <stdexcept>
25 
26 namespace apache
27 {
28 namespace thrift
29 {
30 namespace transport
31 {
32 
33 TWinsockSingleton::instance_ptr TWinsockSingleton::instance_ptr_(NULL);
34 #if USE_BOOST_THREAD
35 boost::once_flag                TWinsockSingleton::flags_ = BOOST_ONCE_INIT;
36 #elif USE_STD_THREAD
37 std::once_flag                  TWinsockSingleton::flags_;
38 #else
39 #error For windows you must choose USE_BOOST_THREAD or USE_STD_THREAD
40 #endif
41 
42 //------------------------------------------------------------------------------
TWinsockSingleton(void)43 TWinsockSingleton::TWinsockSingleton(void)
44 {
45     WORD    version(MAKEWORD(2, 2));
46     WSAData data = {0};
47 
48     int error(WSAStartup(version, &data));
49 
50     if (error != 0)
51     {
52         BOOST_ASSERT(false);
53         throw std::runtime_error("Failed to initialise Winsock.");
54     }
55 }
56 
57 //------------------------------------------------------------------------------
~TWinsockSingleton(void)58 TWinsockSingleton::~TWinsockSingleton(void)
59 {
60     WSACleanup();
61 }
62 
63 //------------------------------------------------------------------------------
create(void)64 void TWinsockSingleton::create(void)
65 {
66 #if USE_BOOST_THREAD
67     boost::call_once(init, flags_);
68 #elif USE_STD_THREAD
69     std::call_once(flags_, init);
70 #endif
71 }
72 
73 //------------------------------------------------------------------------------
init(void)74 void TWinsockSingleton::init(void)
75 {
76     instance_ptr_.reset(new TWinsockSingleton);
77 }
78 
79 }
80 }
81 } // apache::thrift::transport
82