BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmt_semaphoreimpl_win32.h
Go to the documentation of this file.
1/// @file bslmt_semaphoreimpl_win32.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_semaphoreimpl_win32.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_SEMAPHOREIMPL_WIN32
9#define INCLUDED_BSLMT_SEMAPHOREIMPL_WIN32
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_semaphoreimpl_win32 bslmt_semaphoreimpl_win32
15/// @brief Provide a win32 implementation of `bslmt::Semaphore`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_semaphoreimpl_win32
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_semaphoreimpl_win32-purpose"> Purpose</a>
25/// * <a href="#bslmt_semaphoreimpl_win32-classes"> Classes </a>
26/// * <a href="#bslmt_semaphoreimpl_win32-description"> Description </a>
27/// * <a href="#bslmt_semaphoreimpl_win32-usage"> Usage </a>
28///
29/// # Purpose {#bslmt_semaphoreimpl_win32-purpose}
30/// Provide a win32 implementation of `bslmt::Semaphore`.
31///
32/// # Classes {#bslmt_semaphoreimpl_win32-classes}
33///
34/// - bslmt::SemaphoreImpl<Win32Semaphore>: win32 specialization
35///
36/// @see bslmt_semaphore
37///
38/// # Description {#bslmt_semaphoreimpl_win32-description}
39/// This component provides an implementation of `bslmt::Semaphore`
40/// for Windows (win32), `bslmt::SemaphoreImpl<Win32Semaphore>`, via the
41/// template specialization:
42/// @code
43/// bslmt::SemaphoreImpl<Platform::Win32Threads>
44/// @endcode
45/// This template class should not be used (directly) by client code. Clients
46/// should instead use `bslmt::Semaphore`.
47///
48/// ## Usage {#bslmt_semaphoreimpl_win32-usage}
49///
50///
51/// This component is an implementation detail of `bslmt` and is *not* intended
52/// for direct client use. It is subject to change without notice. As such, a
53/// usage example is not provided.
54/// @}
55/** @} */
56/** @} */
57
58/** @addtogroup bsl
59 * @{
60 */
61/** @addtogroup bslmt
62 * @{
63 */
64/** @addtogroup bslmt_semaphoreimpl_win32
65 * @{
66 */
67
68#include <bslscm_version.h>
69
70#include <bslmt_platform.h>
71
72#ifdef BSLMT_PLATFORM_WIN32_THREADS
73
74// Platform-specific implementation starts here.
75
76#include <bsls_assert.h>
77#include <bsls_atomic.h>
78
79#include <bsl_c_limits.h>
80
81struct _SECURITY_ATTRIBUTES;
82typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES;
83typedef struct _SECURITY_ATTRIBUTES *LPSECURITY_ATTRIBUTES;
84typedef long LONG, *LPLONG;
85typedef int BOOL;
86typedef void *HANDLE;
87typedef const char *LPCSTR;
88typedef unsigned long DWORD;
89
90extern "C" {
91
92 __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(
93 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
94 LONG lInitialCount,
95 LONG lMaximumCount,
96 LPCSTR lpName
97 );
98
99 __declspec(dllimport) BOOL __stdcall CloseHandle(
100 HANDLE hObject
101 );
102
103 __declspec(dllimport) BOOL __stdcall ReleaseSemaphore(
104 HANDLE hSemaphore,
105 LONG lReleaseCount,
106 LPLONG lpPreviousCount
107 );
108
109 __declspec(dllimport) DWORD __stdcall WaitForSingleObject(
110 HANDLE hHandle,
111 DWORD dwMilliseconds
112 );
113
114};
115
116
117namespace bslmt {
118
119template <class SEMAPHORE_POLICY>
120class SemaphoreImpl;
121
122 // =============================================
123 // class SemaphoreImpl<Platform::Win32Semaphore>
124 // =============================================
125
126/// This class provides a full specialization of `SemaphoreImpl` for win32.
127/// The implementation provided here defines an efficient POSIX like
128/// semaphore.
129template <>
130class SemaphoreImpl<Platform::Win32Semaphore> {
131
132 // DATA
133 void *d_handle; // TBD doc
134
135 bsls::AtomicInt d_resources; // if positive, number of available
136 // resources if negative: number of waiting
137 // threads (need this because Windows does
138 // not provide a mechanism to get the
139 // semaphore count)
140
141 private:
142 // NOT IMPLEMENTED
143 SemaphoreImpl(const SemaphoreImpl&);
144 SemaphoreImpl& operator=(const SemaphoreImpl&);
145
146 public:
147 // CREATORS
148
149 /// Create a semaphore initially having the specified `count`. This
150 /// method does not return normally unless there are sufficient system
151 /// resources to construct the object.
152 SemaphoreImpl(int count);
153
154 /// Destroy a semaphore
155 ~SemaphoreImpl();
156
157 // MANIPULATORS
158
159 /// Atomically increment the count of this semaphore.
160 void post();
161
162 /// Atomically increment the count of this semaphore by the specified `number`.
163 ///
164 /// \pre The behavior is undefined unless `number > 0`.
165 void post(int number);
166
167 /// Decrement the count of this semaphore if it is positive and return
168 /// 0. Return a non-zero value otherwise.
169 int tryWait();
170
171 /// Block until the count of this semaphore is a positive value and
172 /// atomically decrement it.
173 void wait();
174
175 // ACCESSORS
176
177 /// Return the current value of this semaphore.
178 int getValue() const;
179};
180
181// ============================================================================
182// INLINE DEFINITIONS
183// ============================================================================
184
185 // ---------------------------------------------
186 // class SemaphoreImpl<Platform::Win32Semaphore>
187 // ---------------------------------------------
188
189// CREATORS
190inline
191SemaphoreImpl<bslmt::Platform::Win32Semaphore>::SemaphoreImpl(int count)
192: d_resources(count)
193{
194 // Create a semaphore with a 0 count, since the count is actually
195 // maintained in 'd_resources'.
196
197 d_handle = CreateSemaphoreA(NULL, 0, INT_MAX, NULL);
198 if (NULL == d_handle) {
199 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
200 }
201}
202
203inline
204SemaphoreImpl<bslmt::Platform::Win32Semaphore>::~SemaphoreImpl()
205{
206 CloseHandle(d_handle);
207}
208
209// MANIPULATORS
210inline
211void SemaphoreImpl<bslmt::Platform::Win32Semaphore>::post()
212{
213 if (++d_resources <= 0) {
214 ReleaseSemaphore(d_handle, 1, NULL);
215 }
216}
217
218inline
219void SemaphoreImpl<bslmt::Platform::Win32Semaphore>::wait()
220{
221 if (--d_resources >= 0) {
222 return;
223 }
224 WaitForSingleObject(d_handle, 0xFFFFFFFF /*INFINITE*/);
225}
226
227// ACCESSORS
228inline
229int SemaphoreImpl<bslmt::Platform::Win32Semaphore>::getValue() const
230{
231 const int v = d_resources;
232 return v > 0 ? v : 0;
233}
234
235} // close package namespace
236
237
238#endif // BSLMT_PLATFORM_WIN32_THREADS
239
240#endif
241
242// ----------------------------------------------------------------------------
243// Copyright 2023 Bloomberg Finance L.P.
244//
245// Licensed under the Apache License, Version 2.0 (the "License");
246// you may not use this file except in compliance with the License.
247// You may obtain a copy of the License at
248//
249// http://www.apache.org/licenses/LICENSE-2.0
250//
251// Unless required by applicable law or agreed to in writing, software
252// distributed under the License is distributed on an "AS IS" BASIS,
253// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
254// See the License for the specific language governing permissions and
255// limitations under the License.
256// ----------------------------- END-OF-FILE ----------------------------------
257
258/** @} */
259/** @} */
260/** @} */
Definition bsls_atomic.h:744
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:2101
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslmt_barrier.h:344