~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to include/libtorrent/asio/ssl/detail/openssl_init.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2010-08-10 12:59:37 UTC
  • mfrom: (1.3.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810125937-jbcmmf17y8yo9hgz
Tags: 0.15.0-0ubuntu1
* New upstream version.
* debian/patches/100_fix_html_docs.patch: refreshed.
* debian/control: bump up standards-version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// openssl_init.hpp
3
 
// ~~~~~~~~~~~~~~~~
4
 
//
5
 
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
6
 
// Copyright (c) 2005-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7
 
//
8
 
// Distributed under the Boost Software License, Version 1.0. (See accompanying
9
 
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
 
//
11
 
 
12
 
#ifndef ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
13
 
#define ASIO_SSL_DETAIL_OPENSSL_INIT_HPP
14
 
 
15
 
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
 
# pragma once
17
 
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
 
 
19
 
#include "asio/detail/push_options.hpp"
20
 
 
21
 
#include "asio/detail/push_options.hpp"
22
 
#include <vector>
23
 
#include <boost/assert.hpp>
24
 
#include <boost/config.hpp>
25
 
#include <boost/shared_ptr.hpp>
26
 
#include "asio/detail/pop_options.hpp"
27
 
 
28
 
#include "asio/detail/mutex.hpp"
29
 
#include "asio/detail/tss_ptr.hpp"
30
 
#include "asio/ssl/detail/openssl_types.hpp"
31
 
 
32
 
namespace asio {
33
 
namespace ssl {
34
 
namespace detail {
35
 
 
36
 
template <bool Do_Init = true>
37
 
class openssl_init
38
 
  : private boost::noncopyable
39
 
{
40
 
private:
41
 
  // Structure to perform the actual initialisation.
42
 
  class do_init
43
 
  {
44
 
  public:
45
 
    do_init()
46
 
    {
47
 
      if (Do_Init)
48
 
      {
49
 
        ::SSL_library_init();
50
 
        ::SSL_load_error_strings();        
51
 
        ::OpenSSL_add_ssl_algorithms();
52
 
 
53
 
        mutexes_.resize(::CRYPTO_num_locks());
54
 
        for (size_t i = 0; i < mutexes_.size(); ++i)
55
 
          mutexes_[i].reset(new asio::detail::mutex);
56
 
        ::CRYPTO_set_locking_callback(&do_init::openssl_locking_func);
57
 
        ::CRYPTO_set_id_callback(&do_init::openssl_id_func);
58
 
      }
59
 
    }
60
 
 
61
 
    ~do_init()
62
 
    {
63
 
      if (Do_Init)
64
 
      {
65
 
        ::CRYPTO_set_id_callback(0);
66
 
        ::CRYPTO_set_locking_callback(0);
67
 
        ::ERR_free_strings();
68
 
        ::ERR_remove_state(0);
69
 
        ::EVP_cleanup();
70
 
        ::CRYPTO_cleanup_all_ex_data();
71
 
        ::CONF_modules_unload(1);
72
 
        ::ENGINE_cleanup();
73
 
      }
74
 
    }
75
 
 
76
 
    // Helper function to manage a do_init singleton. The static instance of the
77
 
    // openssl_init object ensures that this function is always called before
78
 
    // main, and therefore before any other threads can get started. The do_init
79
 
    // instance must be static in this function to ensure that it gets
80
 
    // initialised before any other global objects try to use it.
81
 
    static boost::shared_ptr<do_init> instance()
82
 
    {
83
 
      static boost::shared_ptr<do_init> init(new do_init);
84
 
      return init;
85
 
    }
86
 
 
87
 
  private:
88
 
    static unsigned long openssl_id_func()
89
 
    {
90
 
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
91
 
      return ::GetCurrentThreadId();
92
 
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
93
 
      void* id = instance()->thread_id_;
94
 
      if (id == 0)
95
 
        instance()->thread_id_ = id = &id; // Ugh.
96
 
      BOOST_ASSERT(sizeof(unsigned long) >= sizeof(void*));
97
 
      return reinterpret_cast<unsigned long>(id);
98
 
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
99
 
    }
100
 
 
101
 
    static void openssl_locking_func(int mode, int n, 
102
 
      const char *file, int line)
103
 
    {
104
 
      if (mode & CRYPTO_LOCK)
105
 
        instance()->mutexes_[n]->lock();
106
 
      else
107
 
        instance()->mutexes_[n]->unlock();
108
 
    }
109
 
 
110
 
    // Mutexes to be used in locking callbacks.
111
 
    std::vector<boost::shared_ptr<asio::detail::mutex> > mutexes_;
112
 
 
113
 
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
114
 
    // The thread identifiers to be used by openssl.
115
 
    asio::detail::tss_ptr<void> thread_id_;
116
 
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
117
 
  };
118
 
 
119
 
public:
120
 
  // Constructor.
121
 
  openssl_init()
122
 
    : ref_(do_init::instance())
123
 
  {
124
 
    while (&instance_ == 0); // Ensure openssl_init::instance_ is linked in.
125
 
  }
126
 
 
127
 
  // Destructor.
128
 
  ~openssl_init()
129
 
  {
130
 
  }
131
 
 
132
 
private:
133
 
  // Instance to force initialisation of openssl at global scope.
134
 
  static openssl_init instance_;
135
 
 
136
 
  // Reference to singleton do_init object to ensure that openssl does not get
137
 
  // cleaned up until the last user has finished with it.
138
 
  boost::shared_ptr<do_init> ref_;
139
 
};
140
 
 
141
 
template <bool Do_Init>
142
 
openssl_init<Do_Init> openssl_init<Do_Init>::instance_;
143
 
 
144
 
} // namespace detail
145
 
} // namespace ssl
146
 
} // namespace asio
147
 
 
148
 
#include "asio/detail/pop_options.hpp"
149
 
 
150
 
#endif // ASIO_SSL_DETAIL_OPENSSL_INIT_HPP