123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- #ifndef BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
- #define BOOST_ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif
- #include <boost/asio/detail/push_options.hpp>
- #include <boost/asio/detail/push_options.hpp>
- #include <cstring>
- #include <vector>
- #include <boost/assert.hpp>
- #include <boost/config.hpp>
- #include <boost/shared_ptr.hpp>
- #include <boost/asio/detail/pop_options.hpp>
- #include <boost/asio/detail/mutex.hpp>
- #include <boost/asio/detail/tss_ptr.hpp>
- #include <boost/asio/ssl/detail/openssl_types.hpp>
- namespace boost {
- namespace asio {
- namespace ssl {
- namespace detail {
- template <bool Do_Init = true>
- class openssl_init
- : private boost::noncopyable
- {
- private:
-
- class do_init
- {
- public:
- do_init()
- {
- if (Do_Init)
- {
- ::SSL_library_init();
- ::SSL_load_error_strings();
- ::OpenSSL_add_ssl_algorithms();
- mutexes_.resize(::CRYPTO_num_locks());
- for (size_t i = 0; i < mutexes_.size(); ++i)
- mutexes_[i].reset(new boost::asio::detail::mutex);
- ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);
- ::CRYPTO_set_id_callback(&do_init::openssl_id_func);
- }
- }
- ~do_init()
- {
- if (Do_Init)
- {
- ::CRYPTO_set_id_callback(0);
- ::CRYPTO_set_locking_callback(0);
- ::ERR_free_strings();
- ::ERR_remove_state(0);
- ::EVP_cleanup();
- ::CRYPTO_cleanup_all_ex_data();
- ::CONF_modules_unload(1);
- ::ENGINE_cleanup();
- }
- }
-
-
-
-
-
- static boost::shared_ptr<do_init> instance()
- {
- static boost::shared_ptr<do_init> init(new do_init);
- return init;
- }
- private:
- static unsigned long openssl_id_func()
- {
- #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- return ::GetCurrentThreadId();
- #else
- void* id = instance()->thread_id_;
- if (id == 0)
- instance()->thread_id_ = id = &id;
- BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
- return reinterpret_cast<unsigned long>(id);
- #endif
- }
- static void openssl_locking_func(int mode, int n,
- const char* , int )
- {
- if (mode & CRYPTO_LOCK)
- instance()->mutexes_[n]->lock();
- else
- instance()->mutexes_[n]->unlock();
- }
-
- std::vector<boost::shared_ptr<boost::asio::detail::mutex> > mutexes_;
- #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
- boost::asio::detail::tss_ptr<void> thread_id_;
- #endif
- };
- public:
-
- openssl_init()
- : ref_(do_init::instance())
- {
- using namespace std;
-
- openssl_init* tmp = &instance_;
- memmove(&tmp, &tmp, sizeof(openssl_init*));
- }
-
- ~openssl_init()
- {
- }
- private:
-
- static openssl_init instance_;
-
-
- boost::shared_ptr<do_init> ref_;
- };
- template <bool Do_Init>
- openssl_init<Do_Init> openssl_init<Do_Init>::instance_;
- }
- }
- }
- }
- #include <boost/asio/detail/pop_options.hpp>
- #endif
|