BDE 4.14.0 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 // NOT IMPLEMENTED
142 SemaphoreImpl(const SemaphoreImpl&);
143 SemaphoreImpl& operator=(const SemaphoreImpl&);
144
145 public:
146 // CREATORS
147
148 /// Create a semaphore initially having the specified `count`. This
149 /// method does not return normally unless there are sufficient system
150 /// resources to construct the object.
151 SemaphoreImpl(int count);
152
153 /// Destroy a semaphore
154 ~SemaphoreImpl();
155
156 // MANIPULATORS
157
158 /// Atomically increment the count of this semaphore.
159 void post();
160
161 /// Atomically increment the count of this semaphore by the specified
162 /// `number`. The behavior is undefined unless `number > 0`.
163 void post(int number);
164
165 /// Decrement the count of this semaphore if it is positive and return
166 /// 0. Return a non-zero value otherwise.
167 int tryWait();
168
169 /// Block until the count of this semaphore is a positive value and
170 /// atomically decrement it.
171 void wait();
172
173 // ACCESSORS
174
175 /// Return the current value of this semaphore.
176 int getValue() const;
177};
178
179// ============================================================================
180// INLINE DEFINITIONS
181// ============================================================================
182
183 // ---------------------------------------------
184 // class SemaphoreImpl<Platform::Win32Semaphore>
185 // ---------------------------------------------
186
187// CREATORS
188inline
189SemaphoreImpl<bslmt::Platform::Win32Semaphore>::SemaphoreImpl(int count)
190: d_resources(count)
191{
192 // Create a semaphore with a 0 count, since the count is actually
193 // maintained in 'd_resources'.
194
195 d_handle = CreateSemaphoreA(NULL, 0, INT_MAX, NULL);
196 if (NULL == d_handle) {
197 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
198 }
199}
200
201inline
202SemaphoreImpl<bslmt::Platform::Win32Semaphore>::~SemaphoreImpl()
203{
204 CloseHandle(d_handle);
205}
206
207// MANIPULATORS
208inline
209void SemaphoreImpl<bslmt::Platform::Win32Semaphore>::post()
210{
211 if (++d_resources <= 0) {
212 ReleaseSemaphore(d_handle, 1, NULL);
213 }
214}
215
216inline
217void SemaphoreImpl<bslmt::Platform::Win32Semaphore>::wait()
218{
219 if (--d_resources >= 0) {
220 return;
221 }
222 WaitForSingleObject(d_handle, 0xFFFFFFFF /*INFINITE*/);
223}
224
225// ACCESSORS
226inline
227int SemaphoreImpl<bslmt::Platform::Win32Semaphore>::getValue() const
228{
229 const int v = d_resources;
230 return v > 0 ? v : 0;
231}
232
233} // close package namespace
234
235
236#endif // BSLMT_PLATFORM_WIN32_THREADS
237
238#endif
239
240// ----------------------------------------------------------------------------
241// Copyright 2023 Bloomberg Finance L.P.
242//
243// Licensed under the Apache License, Version 2.0 (the "License");
244// you may not use this file except in compliance with the License.
245// You may obtain a copy of the License at
246//
247// http://www.apache.org/licenses/LICENSE-2.0
248//
249// Unless required by applicable law or agreed to in writing, software
250// distributed under the License is distributed on an "AS IS" BASIS,
251// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
252// See the License for the specific language governing permissions and
253// limitations under the License.
254// ----------------------------- END-OF-FILE ----------------------------------
255
256/** @} */
257/** @} */
258/** @} */
Definition bsls_atomic.h:743
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:1895
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslmt_barrier.h:344