BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_timedsemaphoreimpl_win32.h
Go to the documentation of this file.
1/// @file bslmt_timedsemaphoreimpl_win32.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_timedsemaphoreimpl_win32.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_TIMEDSEMAPHOREIMPL_WIN32
9#define INCLUDED_BSLMT_TIMEDSEMAPHOREIMPL_WIN32
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_timedsemaphoreimpl_win32 bslmt_timedsemaphoreimpl_win32
15/// @brief Provide a win32 implementation of `bslmt::TimedSemaphore`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_timedsemaphoreimpl_win32
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_timedsemaphoreimpl_win32-purpose"> Purpose</a>
25/// * <a href="#bslmt_timedsemaphoreimpl_win32-classes"> Classes </a>
26/// * <a href="#bslmt_timedsemaphoreimpl_win32-description"> Description </a>
27/// * <a href="#bslmt_timedsemaphoreimpl_win32-supported-clock-types"> Supported Clock-Types </a>
28/// * <a href="#bslmt_timedsemaphoreimpl_win32-usage"> Usage </a>
29///
30/// # Purpose {#bslmt_timedsemaphoreimpl_win32-purpose}
31/// Provide a win32 implementation of `bslmt::TimedSemaphore`.
32///
33/// # Classes {#bslmt_timedsemaphoreimpl_win32-classes}
34///
35/// - bslmt::TimedSemaphoreImpl<Win32TimedSemaphore>: win32 specialization
36///
37/// @see bslmt_timedsemaphore
38///
39/// # Description {#bslmt_timedsemaphoreimpl_win32-description}
40/// This component provides an implementation of
41/// `bslmt::TimedSemaphore` for Windows (win32),
42/// `bslmt::TimedSemaphoreImpl<Win32TimedSemaphore>`, via the template
43/// specialization:
44/// @code
45/// bslmt::TimedSemaphoreImpl<Platform::Win32Threads>
46/// @endcode
47/// This template class should not be used (directly) by client code. Clients
48/// should instead use `bslmt::TimedSemaphore`.
49///
50/// ## Supported Clock-Types {#bslmt_timedsemaphoreimpl_win32-supported-clock-types}
51///
52///
53/// `bsls::SystemClockType` supplies the enumeration indicating the system clock
54/// on which timeouts supplied to other methods should be based. If the clock
55/// type indicated at construction is `bsls::SystemClockType::e_REALTIME`, the
56/// `absTime` argument passed to the `timedWait` method should be expressed as
57/// an *absolute* offset since 00:00:00 UTC, January 1, 1970 (which matches the
58/// epoch used in `bsls::SystemTime::now(bsls::SystemClockType::e_REALTIME)`.
59/// If the clock type indicated at construction is
60/// `bsls::SystemClockType::e_MONOTONIC`, the `absTime` argument passed to the
61/// `timedWait` method should be expressed as an *absolute* offset since the
62/// epoch of this clock (which matches the epoch used in
63/// `bsls::SystemTime::now(bsls::SystemClockType::e_MONOTONIC)`.
64///
65/// ## Usage {#bslmt_timedsemaphoreimpl_win32-usage}
66///
67///
68/// This component is an implementation detail of `bslmt` and is *not* intended
69/// for direct client use. It is subject to change without notice. As such, a
70/// usage example is not provided.
71/// @}
72/** @} */
73/** @} */
74
75/** @addtogroup bsl
76 * @{
77 */
78/** @addtogroup bslmt
79 * @{
80 */
81/** @addtogroup bslmt_timedsemaphoreimpl_win32
82 * @{
83 */
84
85#include <bslscm_version.h>
86
87#include <bslmt_platform.h>
88
89#ifdef BSLMT_PLATFORM_WIN32_THREADS
90
91// Platform-specific implementation starts here.
92
93#include <bsls_assert.h>
95#include <bsls_timeinterval.h>
96
97#include <bsl_c_limits.h>
98
99struct _SECURITY_ATTRIBUTES;
100typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES;
101typedef struct _SECURITY_ATTRIBUTES *LPSECURITY_ATTRIBUTES;
102typedef long LONG, *LPLONG;
103typedef int BOOL;
104typedef void *HANDLE;
105typedef const char *LPCSTR;
106typedef unsigned long DWORD;
107
108extern "C" {
109
110 __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(
111 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
112 LONG lInitialCount,
113 LONG lMaximumCount,
114 LPCSTR lpName
115 );
116
117 __declspec(dllimport) BOOL __stdcall CloseHandle(
118 HANDLE hObject
119 );
120
121 __declspec(dllimport) BOOL __stdcall ReleaseSemaphore(
122 HANDLE hSemaphore,
123 LONG lReleaseCount,
124 LPLONG lpPreviousCount
125 );
126
127 __declspec(dllimport) DWORD __stdcall WaitForSingleObject(
128 HANDLE hHandle,
129 DWORD dwMilliseconds
130 );
131
132};
133
134
135namespace bslmt {
136
137template <class TIMED_SEMAPHORE_POLICY>
138class TimedSemaphoreImpl;
139
140 // =============================================
141 // class TimedSemaphoreImpl<Win32TimedSemaphore>
142 // =============================================
143
144/// This class implements a timed semaphore in terms of Windows semaphores.
145template <>
146class TimedSemaphoreImpl<Platform::Win32TimedSemaphore> {
147
148 // DATA
149 void *d_handle; // handle to Window's
150 // implementation of timed
151 // semaphore
152
153 bsls::SystemClockType::Enum d_clockType; // clock used in timedWait
154
155 // NOT IMPLEMENTED
156 TimedSemaphoreImpl(const TimedSemaphoreImpl&);
157 TimedSemaphoreImpl& operator=(const TimedSemaphoreImpl&);
158
159 public:
160 // TYPES
161
162 /// The value `timedWait` returns when a timeout occurs.
163 enum { e_TIMED_OUT = 0x102 };
164
165 // CREATORS
166
167 /// Create a timed semaphore initially having a count of 0. Optionally
168 /// specify a `clockType` indicating the type of the system clock
169 /// against which the `bsls::TimeInterval` `absTime` timeouts passed to
170 /// the `timedWait` method are to be interpreted (see {Supported
171 /// Clock-Types} in the component documentation). If `clockType` is not
172 /// specified then the realtime system clock is used. This method does
173 /// not return normally unless there are sufficient system resources to
174 /// construct the object.
175 explicit
176 TimedSemaphoreImpl(bsls::SystemClockType::Enum clockType
178
179 /// Create a timed semaphore initially having the specified `count`.
180 /// Optionally specify a `clockType` indicating the type of the system
181 /// clock against which the `bsls::TimeInterval` `absTime` timeouts
182 /// passed to the `timedWait` method are to be interpreted (see
183 /// {Supported Clock-Types} in the component documentation). If
184 /// `clockType` is not specified then the realtime system clock is used.
185 /// This method does not return normally unless there are sufficient
186 /// system resources to construct the object.
187 explicit
188 TimedSemaphoreImpl(int count,
191
192 /// Destroy this semaphore object.
193 ~TimedSemaphoreImpl();
194
195 // MANIPULATORS
196
197 /// Atomically increment the count of the semaphore.
198 void post();
199
200 /// Atomically increment the count by the specified `number` of the
201 /// semaphore. The behavior is undefined unless `number` is a positive
202 /// value.
203 void post(int number);
204
205 /// Block until the count of this semaphore is a positive value, or
206 /// until the specified `absTime` timeout expires. `absTime` is an
207 /// *absolute* time represented as an interval from some epoch, which is
208 /// determined by the clock indicated at construction (see {Supported
209 /// Clock-Types} in the component documentation). If the timeout did
210 /// not expire before the count attained a positive value, atomically
211 /// decrement the count and return 0; otherwise, return a non-zero value
212 /// with no effect on the count. This method may return `e_TIMED_OUT`
213 /// slightly before `absTime`.
214 int timedWait(const bsls::TimeInterval& absTime);
215
216 /// Decrement the count of this semaphore if it is positive and return 0.
217 /// Return a non-zero value otherwise.
218 int tryWait();
219
220 /// Block until the count is a positive value and atomically decrement it.
221 void wait();
222
223 // ACCESSORS
224
225 /// Return the clock type used for timeouts.
226 bsls::SystemClockType::Enum clockType() const;
227};
228
229// ============================================================================
230// INLINE DEFINITIONS
231// ============================================================================
232
233 // ---------------------------------------------
234 // class TimedSemaphoreImpl<Win32TimedSemaphore>
235 // ---------------------------------------------
236
237// CREATORS
238inline
239TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
240 TimedSemaphoreImpl(bsls::SystemClockType::Enum clockType)
241: d_clockType(clockType)
242{
243 d_handle = CreateSemaphoreA(NULL, 0, INT_MAX, NULL);
244 if (NULL == d_handle) {
245 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
246 }
247}
248
249inline
250TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
251 TimedSemaphoreImpl(int count, bsls::SystemClockType::Enum clockType)
252: d_clockType(clockType)
253{
254 d_handle = CreateSemaphoreA(NULL, count, INT_MAX, NULL);
255 if (NULL == d_handle) {
256 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
257 }
258}
259
260inline
261TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
262 ~TimedSemaphoreImpl()
263{
264 CloseHandle(d_handle);
265}
266
267// MANIPULATORS
268inline
269void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::post()
270{
271 ReleaseSemaphore(d_handle, 1, NULL);
272}
273
274inline
275void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
276 post(int number)
277{
278 ReleaseSemaphore(d_handle, number, NULL);
279}
280
281inline
282int TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::tryWait()
283{
284 return WaitForSingleObject(d_handle, 0); // 0 means timeout immediately.
285}
286
287inline
288void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::wait()
289{
290 WaitForSingleObject(d_handle, 0xFFFFFFFF /* INFINITE */);
291}
292
293// ACCESSORS
294inline
296TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
297 clockType() const
298{
299 return d_clockType;
300}
301
302} // close package namespace
303
304
305#endif // BSLMT_PLATFORM_WIN32_THREADS
306
307#endif
308
309// ----------------------------------------------------------------------------
310// Copyright 2023 Bloomberg Finance L.P.
311//
312// Licensed under the Apache License, Version 2.0 (the "License");
313// you may not use this file except in compliance with the License.
314// You may obtain a copy of the License at
315//
316// http://www.apache.org/licenses/LICENSE-2.0
317//
318// Unless required by applicable law or agreed to in writing, software
319// distributed under the License is distributed on an "AS IS" BASIS,
320// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
321// See the License for the specific language governing permissions and
322// limitations under the License.
323// ----------------------------- END-OF-FILE ----------------------------------
324
325/** @} */
326/** @} */
327/** @} */
Definition bsls_timeinterval.h:301
#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
Enum
Definition bsls_systemclocktype.h:117
@ e_REALTIME
Definition bsls_systemclocktype.h:120