]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/thread/src/pthread/once.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / thread / src / pthread / once.cpp
CommitLineData
7c673cae
FG
1// Copyright (C) 2007 Anthony Williams
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/thread/detail/config.hpp>
7#ifdef BOOST_THREAD_ONCE_ATOMIC
8#include "./once_atomic.cpp"
9#else
10#define __STDC_CONSTANT_MACROS
7c673cae
FG
11#include <boost/thread/once.hpp>
12#include <boost/assert.hpp>
13#include <boost/throw_exception.hpp>
14#include <pthread.h>
15#include <stdlib.h>
16#include <memory>
17#include <string.h> // memcmp.
18namespace boost
19{
20 namespace thread_detail
21 {
22 BOOST_THREAD_DECL uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
23 BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
24 BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
25
26 namespace
27 {
28 pthread_key_t epoch_tss_key;
29 pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT;
30
31 extern "C"
32 {
33 static void delete_epoch_tss_data(void* data)
34 {
35 free(data);
36 }
37
38 static void create_epoch_tss_key()
39 {
40 BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
41 }
42 }
43
44#if defined BOOST_THREAD_PATCH
45 const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT;
46 struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t
47 {
48 delete_epoch_tss_key_on_dlclose_t()
49 {
50 }
51 ~delete_epoch_tss_key_on_dlclose_t()
52 {
53 if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t)))
54 {
55 void* data = pthread_getspecific(epoch_tss_key);
56 if (data)
57 delete_epoch_tss_data(data);
58 pthread_key_delete(epoch_tss_key);
59 }
60 }
61 };
62 delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
63#endif
64 }
65
66 uintmax_atomic_t& get_once_per_thread_epoch()
67 {
68 BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
69 void* data=pthread_getspecific(epoch_tss_key);
70 if(!data)
71 {
72 data=malloc(sizeof(thread_detail::uintmax_atomic_t));
73 if(!data) BOOST_THROW_EXCEPTION(std::bad_alloc());
74 BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
75 *static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
76 }
77 return *static_cast<thread_detail::uintmax_atomic_t*>(data);
78 }
79 }
80
81}
82#endif //