blob: a5b2ac50f0d650eedbf10c4d8da5ae411224cf1f [file] [log] [blame]
Ben Craigb2501a72013-09-13 12:29:43 -05001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#ifndef _THRIFT_WINDOWS_Sync_H_
21#define _THRIFT_WINDOWS_Sync_H_ 1
22
23#ifndef _WIN32
24#error "windows/Sync.h is only usable on Windows"
25#endif
26
27#include <thrift/concurrency/Exception.h>
Mario Emmenlauerd270b352020-11-19 09:43:34 +010028#include <thrift/TNonCopyable.h>
29
Mario Emmenlauer034c9352020-05-21 23:04:12 +020030// Including Windows.h can conflict with Winsock2 usage, and also
31// adds problematic macros like min() and max(). Try to work around:
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010032#ifndef NOMINMAX
Mario Emmenlauer034c9352020-05-21 23:04:12 +020033#define NOMINMAX
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010034#define _THRIFT_UNDEF_NOMINMAX
35#endif
36#ifndef WIN32_LEAN_AND_MEAN
Mario Emmenlauer034c9352020-05-21 23:04:12 +020037#define WIN32_LEAN_AND_MEAN
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010038#define _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
39#endif
Ben Craigb2501a72013-09-13 12:29:43 -050040#include <Windows.h>
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010041#ifdef _THRIFT_UNDEF_NOMINMAX
Mario Emmenlauer034c9352020-05-21 23:04:12 +020042#undef NOMINMAX
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010043#undef _THRIFT_UNDEF_NOMINMAX
44#endif
45#ifdef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
Mario Emmenlauer034c9352020-05-21 23:04:12 +020046#undef WIN32_LEAN_AND_MEAN
Dirk Sandbrinkcbb65302022-02-04 09:55:19 +010047#undef _THRIFT_UNDEF_WIN32_LEAN_AND_MEAN
48#endif
Ben Craigb2501a72013-09-13 12:29:43 -050049
50/*
51 Lightweight synchronization objects that only make sense on Windows. For cross-platform
52 code, use the classes found in the concurrency namespace
53*/
54
Konrad Grochowski16a23a62014-11-13 15:33:38 +010055namespace apache {
56namespace thrift {
Ben Craigb2501a72013-09-13 12:29:43 -050057
Mario Emmenlauerd270b352020-11-19 09:43:34 +010058struct TCriticalSection : apache::thrift::TNonCopyable {
Ben Craigb2501a72013-09-13 12:29:43 -050059 CRITICAL_SECTION cs;
Konrad Grochowski16a23a62014-11-13 15:33:38 +010060 TCriticalSection() { InitializeCriticalSection(&cs); }
61 ~TCriticalSection() { DeleteCriticalSection(&cs); }
Ben Craigb2501a72013-09-13 12:29:43 -050062};
63
Mario Emmenlauerd270b352020-11-19 09:43:34 +010064class TAutoCrit : apache::thrift::TNonCopyable {
Ben Craigb2501a72013-09-13 12:29:43 -050065private:
Konrad Grochowski16a23a62014-11-13 15:33:38 +010066 CRITICAL_SECTION* cs_;
67
Ben Craigb2501a72013-09-13 12:29:43 -050068public:
Konrad Grochowski16a23a62014-11-13 15:33:38 +010069 explicit TAutoCrit(TCriticalSection& cs) : cs_(&cs.cs) { EnterCriticalSection(cs_); }
70 ~TAutoCrit() { LeaveCriticalSection(cs_); }
Ben Craigb2501a72013-09-13 12:29:43 -050071};
72
Mario Emmenlauerd270b352020-11-19 09:43:34 +010073struct TAutoResetEvent : apache::thrift::TNonCopyable {
Ben Craigb2501a72013-09-13 12:29:43 -050074 HANDLE h;
75
76 TAutoResetEvent() {
zeshuai00726681fb2020-06-03 17:24:38 +080077 h = CreateEvent(nullptr, FALSE, FALSE, nullptr);
78 if (h == nullptr) {
Ben Craigb2501a72013-09-13 12:29:43 -050079 GlobalOutput.perror("TAutoResetEvent unable to create event, GLE=", GetLastError());
80 throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed");
81 }
82 }
Konrad Grochowski16a23a62014-11-13 15:33:38 +010083 ~TAutoResetEvent() { CloseHandle(h); }
Ben Craigb2501a72013-09-13 12:29:43 -050084};
85
Mario Emmenlauerd270b352020-11-19 09:43:34 +010086struct TManualResetEvent : apache::thrift::TNonCopyable {
Ben Craigb2501a72013-09-13 12:29:43 -050087 HANDLE h;
88
89 TManualResetEvent() {
zeshuai00726681fb2020-06-03 17:24:38 +080090 h = CreateEvent(nullptr, TRUE, FALSE, nullptr);
91 if (h == nullptr) {
Ben Craigb2501a72013-09-13 12:29:43 -050092 GlobalOutput.perror("TManualResetEvent unable to create event, GLE=", GetLastError());
93 throw apache::thrift::concurrency::SystemResourceException("CreateEvent failed");
94 }
95 }
Konrad Grochowski16a23a62014-11-13 15:33:38 +010096 ~TManualResetEvent() { CloseHandle(h); }
Ben Craigb2501a72013-09-13 12:29:43 -050097};
98
Mario Emmenlauerd270b352020-11-19 09:43:34 +010099struct TAutoHandle : apache::thrift::TNonCopyable {
Ben Craigb2501a72013-09-13 12:29:43 -0500100 HANDLE h;
101 explicit TAutoHandle(HANDLE h_ = INVALID_HANDLE_VALUE) : h(h_) {}
102 ~TAutoHandle() {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100103 if (h != INVALID_HANDLE_VALUE)
Ben Craigb2501a72013-09-13 12:29:43 -0500104 CloseHandle(h);
105 }
106
107 HANDLE release() {
108 HANDLE retval = h;
109 h = INVALID_HANDLE_VALUE;
110 return retval;
111 }
112 void reset(HANDLE h_ = INVALID_HANDLE_VALUE) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100113 if (h_ == h)
Ben Craigb2501a72013-09-13 12:29:43 -0500114 return;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100115 if (h != INVALID_HANDLE_VALUE)
Ben Craigb2501a72013-09-13 12:29:43 -0500116 CloseHandle(h);
117 h = h_;
118 }
119};
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100120}
121} // apache::thrift
Ben Craigb2501a72013-09-13 12:29:43 -0500122
123#endif