blob: c7d26594d854bfc1380483928fba38306b3de5c1 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001/*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE static_mutex.hpp
15 * VERSION see <ndnboost/version.hpp>
16 * DESCRIPTION: Declares static_mutex lock type, there are three different
17 * implementations: POSIX pthreads, WIN32 threads, and portable,
18 * these are described in more detail below.
19 */
20
21#ifndef NDNBOOST_REGEX_STATIC_MUTEX_HPP
22#define NDNBOOST_REGEX_STATIC_MUTEX_HPP
23
24#include <ndnboost/config.hpp>
25#include <ndnboost/regex/config.hpp> // dll import/export options.
26
27#ifdef NDNBOOST_HAS_PTHREADS
28#include <pthread.h>
29#endif
30
31#if defined(NDNBOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
32//
33// pthreads version:
34// simple wrap around a pthread_mutex_t initialized with
35// PTHREAD_MUTEX_INITIALIZER.
36//
37namespace ndnboost{
38
39class static_mutex;
40
41#define NDNBOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
42
43class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
44{
45public:
46 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
47 ~scoped_static_mutex_lock();
48 inline bool locked()const
49 {
50 return m_have_lock;
51 }
52 inline operator void const*()const
53 {
54 return locked() ? this : 0;
55 }
56 void lock();
57 void unlock();
58private:
59 static_mutex& m_mutex;
60 bool m_have_lock;
61};
62
63class static_mutex
64{
65public:
66 typedef scoped_static_mutex_lock scoped_lock;
67 pthread_mutex_t m_mutex;
68};
69
70} // namespace ndnboost
71#elif defined(NDNBOOST_HAS_WINTHREADS)
72//
73// Win32 version:
74// Use a 32-bit int as a lock, along with a test-and-set
75// implementation using InterlockedCompareExchange.
76//
77
78#include <ndnboost/cstdint.hpp>
79
80namespace ndnboost{
81
82class NDNBOOST_REGEX_DECL scoped_static_mutex_lock;
83
84class static_mutex
85{
86public:
87 typedef scoped_static_mutex_lock scoped_lock;
88 ndnboost::int32_t m_mutex;
89};
90
91#define NDNBOOST_STATIC_MUTEX_INIT { 0, }
92
93class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
94{
95public:
96 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
97 ~scoped_static_mutex_lock();
98 operator void const*()const
99 {
100 return locked() ? this : 0;
101 }
102 bool locked()const
103 {
104 return m_have_lock;
105 }
106 void lock();
107 void unlock();
108private:
109 static_mutex& m_mutex;
110 bool m_have_lock;
111 scoped_static_mutex_lock(const scoped_static_mutex_lock&);
112 scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
113};
114
115} // namespace
116
117#else
118//
119// Portable version of a static mutex based on Boost.Thread library:
120// This has to use a single mutex shared by all instances of static_mutex
121// because ndnboost::call_once doesn't alow us to pass instance information
122// down to the initialisation proceedure. In fact the initialisation routine
123// may need to be called more than once - but only once per instance.
124//
125// Since this preprocessor path is almost never taken, we hide these header
126// dependencies so that build tools don't find them.
127//
128#define B1 <ndnboost/thread/once.hpp>
129#define B2 <ndnboost/thread/recursive_mutex.hpp>
130#include B1
131#include B2
132#undef B1
133#undef B2
134
135namespace ndnboost{
136
137class NDNBOOST_REGEX_DECL scoped_static_mutex_lock;
138extern "C" NDNBOOST_REGEX_DECL void ndnboost_regex_free_static_mutex();
139
140class NDNBOOST_REGEX_DECL static_mutex
141{
142public:
143 typedef scoped_static_mutex_lock scoped_lock;
144 static void init();
145 static ndnboost::recursive_mutex* m_pmutex;
146 static ndnboost::once_flag m_once;
147};
148
149#define NDNBOOST_STATIC_MUTEX_INIT { }
150
151class NDNBOOST_REGEX_DECL scoped_static_mutex_lock
152{
153public:
154 scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
155 ~scoped_static_mutex_lock();
156 operator void const*()const;
157 bool locked()const;
158 void lock();
159 void unlock();
160private:
161 ndnboost::recursive_mutex::scoped_lock* m_plock;
162 bool m_have_lock;
163};
164
165inline scoped_static_mutex_lock::operator void const*()const
166{
167 return locked() ? this : 0;
168}
169
170inline bool scoped_static_mutex_lock::locked()const
171{
172 return m_have_lock;
173}
174
175} // namespace
176
177#endif
178
179#endif