BDE 4.39.x 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 private:
156 // NOT IMPLEMENTED
157 TimedSemaphoreImpl(const TimedSemaphoreImpl&);
158 TimedSemaphoreImpl& operator=(const TimedSemaphoreImpl&);
159
160 public:
161 // TYPES
162
163 /// The value `timedWait` returns when a timeout occurs.
164 enum { e_TIMED_OUT = 0x102 };
165
166 // CREATORS
167
168 /// Create a timed semaphore initially having a count of 0. Optionally
169 /// specify a `clockType` indicating the type of the system clock
170 /// against which the `bsls::TimeInterval` `absTime` timeouts passed to
171 /// the `timedWait` method are to be interpreted (see {Supported
172 /// Clock-Types} in the component documentation). If `clockType` is not
173 /// specified then the realtime system clock is used. This method does
174 /// not return normally unless there are sufficient system resources to
175 /// construct the object.
176 explicit
177 TimedSemaphoreImpl(bsls::SystemClockType::Enum clockType
179
180 /// Create a timed semaphore initially having the specified `count`.
181 /// Optionally specify a `clockType` indicating the type of the system
182 /// clock against which the `bsls::TimeInterval` `absTime` timeouts
183 /// passed to the `timedWait` method are to be interpreted (see
184 /// {Supported Clock-Types} in the component documentation). If
185 /// `clockType` is not specified then the realtime system clock is used.
186 /// This method does not return normally unless there are sufficient
187 /// system resources to construct the object.
188 explicit
189 TimedSemaphoreImpl(int count,
192
193 /// Destroy this semaphore object.
194 ~TimedSemaphoreImpl();
195
196 // MANIPULATORS
197
198 /// Atomically increment the count of the semaphore.
199 void post();
200
201 /// Atomically increment the count by the specified `number` of the semaphore.
202 ///
203 /// \pre The behavior is undefined unless `number` is a positive
204 /// value.
205 void post(int number);
206
207 /// Block until the count of this semaphore is a positive value, or
208 /// until the specified `absTime` timeout expires. `absTime` is an
209 /// *absolute* time represented as an interval from some epoch, which is
210 /// determined by the clock indicated at construction (see {Supported
211 /// Clock-Types} in the component documentation). If the timeout did
212 /// not expire before the count attained a positive value, atomically
213 /// decrement the count and return 0; otherwise, return a non-zero value
214 /// with no effect on the count. This method may return `e_TIMED_OUT`
215 /// slightly before `absTime`.
216 int timedWait(const bsls::TimeInterval& absTime);
217
218 /// Decrement the count of this semaphore if it is positive and return 0.
219 /// Return a non-zero value otherwise.
220 int tryWait();
221
222 /// Block until the count is a positive value and atomically decrement it.
223 void wait();
224
225 // ACCESSORS
226
227 /// Return the clock type used for timeouts.
228 bsls::SystemClockType::Enum clockType() const;
229};
230
231// ============================================================================
232// INLINE DEFINITIONS
233// ============================================================================
234
235 // ---------------------------------------------
236 // class TimedSemaphoreImpl<Win32TimedSemaphore>
237 // ---------------------------------------------
238
239// CREATORS
240inline
241TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
242 TimedSemaphoreImpl(bsls::SystemClockType::Enum clockType)
243: d_clockType(clockType)
244{
245 d_handle = CreateSemaphoreA(NULL, 0, INT_MAX, NULL);
246 if (NULL == d_handle) {
247 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
248 }
249}
250
251inline
252TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
253 TimedSemaphoreImpl(int count, bsls::SystemClockType::Enum clockType)
254: d_clockType(clockType)
255{
256 d_handle = CreateSemaphoreA(NULL, count, INT_MAX, NULL);
257 if (NULL == d_handle) {
258 BSLS_ASSERT_INVOKE_NORETURN("'CreateSemaphoreA' failed");
259 }
260}
261
262inline
263TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
264 ~TimedSemaphoreImpl()
265{
266 CloseHandle(d_handle);
267}
268
269// MANIPULATORS
270inline
271void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::post()
272{
273 ReleaseSemaphore(d_handle, 1, NULL);
274}
275
276inline
277void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
278 post(int number)
279{
280 ReleaseSemaphore(d_handle, number, NULL);
281}
282
283inline
284int TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::tryWait()
285{
286 return WaitForSingleObject(d_handle, 0); // 0 means timeout immediately.
287}
288
289inline
290void TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::wait()
291{
292 WaitForSingleObject(d_handle, 0xFFFFFFFF /* INFINITE */);
293}
294
295// ACCESSORS
296inline
298TimedSemaphoreImpl<bslmt::Platform::Win32TimedSemaphore>::
299 clockType() const
300{
301 return d_clockType;
302}
303
304} // close package namespace
305
306
307#endif // BSLMT_PLATFORM_WIN32_THREADS
308
309#endif
310
311// ----------------------------------------------------------------------------
312// Copyright 2023 Bloomberg Finance L.P.
313//
314// Licensed under the Apache License, Version 2.0 (the "License");
315// you may not use this file except in compliance with the License.
316// You may obtain a copy of the License at
317//
318// http://www.apache.org/licenses/LICENSE-2.0
319//
320// Unless required by applicable law or agreed to in writing, software
321// distributed under the License is distributed on an "AS IS" BASIS,
322// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
323// See the License for the specific language governing permissions and
324// limitations under the License.
325// ----------------------------- END-OF-FILE ----------------------------------
326
327/** @} */
328/** @} */
329/** @} */
Definition bsls_timeinterval.h:307
#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
Enum
Definition bsls_systemclocktype.h:119
@ e_REALTIME
Definition bsls_systemclocktype.h:122