KiCad PCB EDA Suite
kicad_curl.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 Mark Roszko <mark.roszko@gmail.com>
5  * Copyright (C) 2016 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 // kicad_curl.h must be included before wx headers, to avoid
27 // conflicts for some defines, at least on Windows
28 #include <kicad_curl/kicad_curl.h>
29 
30 #include <mutex>
31 #include <ki_exception.h> // THROW_IO_ERROR
32 
33 
34 
35 // These are even more private than class members, and since there is only
36 // one instance of KICAD_CURL ever, these statics are hidden here to simplify the
37 // client (API) header file.
38 static volatile bool s_initialized;
39 
40 static std::mutex s_lock; // for s_initialized
41 
44 static void at_terminate()
45 {
47 }
48 
49 
51 {
52  // We test s_initialized twice in an effort to avoid
53  // unnecessarily locking s_lock. This understands that the common case
54  // will not need to lock.
55  if( !s_initialized )
56  {
57  std::lock_guard<std::mutex> lock( s_lock );
58 
59  if( !s_initialized )
60  {
61  if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
62  {
63  THROW_IO_ERROR( "curl_global_init() failed." );
64  }
65 
66  s_initialized = true;
67  }
68  }
69 }
70 
71 
73 {
74  /*
75 
76  Calling lock_guard() from a static destructor will typically be bad, since the
77  s_lock may already have been statically destroyed itself leading to a boost
78  exception. (Remember C++ does not provide certain sequencing of static
79  destructor invocation.)
80 
81  To prevent this we test s_initialized twice, which ensures that the lock_guard
82  is only instantiated on the first call, which should be from
83  PGM_BASE::destroy() which is first called earlier than static destruction.
84  Then when called again from the actual PGM_BASE::~PGM_BASE() function,
85  lock_guard will not be instantiated because s_initialized will be false.
86 
87  */
88 
89  if( s_initialized )
90  {
91  std::lock_guard<std::mutex> lock( s_lock );
92 
93  if( s_initialized )
94  {
95  curl_global_cleanup();
96 
97  atexit( &at_terminate );
98 
99  s_initialized = false;
100  }
101  }
102 }
103 
104 
106 {
107  if( !s_initialized )
108  Init();
109 
110  curl_version_info_data* info = curl_version_info( CURLVERSION_NOW );
111 
112  std::string res;
113 
114  if( info->version )
115  {
116  res += "libcurl version: " + std::string( info->version );
117  }
118 
119  res += " (";
120 
121  if( info->features & CURL_VERSION_SSL )
122  {
123  res += "with SSL - ";
124  res += std::string( info->ssl_version );
125  }
126  else
127  {
128  res += "without SSL";
129  }
130  res += ")";
131 
132  return res;
133 }
134 
135 
136 std::string GetKicadCurlVersion()
137 {
138  return KICAD_CURL::GetVersion();
139 }
140 
141 
142 std::string GetCurlLibVersion()
143 {
144  return LIBCURL_VERSION;
145 }
static std::mutex s_lock
Definition: kicad_curl.cpp:40
static void Cleanup()
Call curl_global_cleanup for the application.
Definition: kicad_curl.cpp:72
static void Init()
Call curl_global_init for the application.
Definition: kicad_curl.cpp:50
static void at_terminate()
At process termination, using atexit() keeps the CURL stuff out of the singletops and PGM_BASE.
Definition: kicad_curl.cpp:44
std::string GetKicadCurlVersion()
Definition: kicad_curl.cpp:136
std::string GetCurlLibVersion()
Definition: kicad_curl.cpp:142
static volatile bool s_initialized
Definition: kicad_curl.cpp:38
static const char * GetVersion()
Wrapper for curl_version().
Definition: kicad_curl.h:87
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
static std::string GetSimpleVersion()
Report back curl version only and SSL library support.
Definition: kicad_curl.cpp:105