Skip to content

Commit 64a60b4

Browse files
<xthreads.h>: Use enum class _Thrd_result for type safety (#3897)
1 parent 92d050e commit 64a60b4

File tree

8 files changed

+66
-66
lines changed

8 files changed

+66
-66
lines changed

stl/inc/condition_variable

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ private:
238238
const shared_ptr<mutex> _Ptr = _Myptr; // for immunity to *this destruction
239239
unique_lock<mutex> _Guard{*_Ptr};
240240
_Unlock_guard<_Lock> _Unlock_outer{_Lck};
241-
const int _Res = _Cnd_timedwait(_Mycnd(), _Ptr->_Mymtx(), _Abs_time);
241+
const _Thrd_result _Res = _Cnd_timedwait(_Mycnd(), _Ptr->_Mymtx(), _Abs_time);
242242
_Guard.unlock();
243243

244-
if (_Res == _Thrd_success) {
244+
if (_Res == _Thrd_result::_Success) {
245245
return cv_status::no_timeout;
246246
} else {
247247
return cv_status::timeout;

stl/inc/mutex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public:
5353
_Mutex_base& operator=(const _Mutex_base&) = delete;
5454

5555
void lock() {
56-
if (_Mtx_lock(_Mymtx()) != _Thrd_success) {
56+
if (_Mtx_lock(_Mymtx()) != _Thrd_result::_Success) {
5757
// undefined behavior, only occurs for plain mutexes (N4950 [thread.mutex.requirements.mutex.general]/6)
5858
_STD _Throw_Cpp_error(_RESOURCE_DEADLOCK_WOULD_OCCUR);
5959
}
@@ -68,7 +68,7 @@ public:
6868

6969
_NODISCARD_TRY_CHANGE_STATE bool try_lock() noexcept /* strengthened */ {
7070
// false may be from undefined behavior for plain mutexes (N4950 [thread.mutex.requirements.mutex.general]/6)
71-
return _Mtx_trylock(_Mymtx()) == _Thrd_success;
71+
return _Mtx_trylock(_Mymtx()) == _Thrd_result::_Success;
7272
}
7373

7474
void unlock() noexcept /* strengthened */ {
@@ -718,9 +718,9 @@ private:
718718
}
719719

720720
// Nothing to do to comply with LWG-2135 because std::mutex lock/unlock are nothrow
721-
const int _Res = _Cnd_timedwait(_Mycnd(), _Lck.mutex()->_Mymtx(), _Abs_time);
721+
const _Thrd_result _Res = _Cnd_timedwait(_Mycnd(), _Lck.mutex()->_Mymtx(), _Abs_time);
722722

723-
if (_Res == _Thrd_success) {
723+
if (_Res == _Thrd_result::_Success) {
724724
return cv_status::no_timeout;
725725
} else {
726726
return cv_status::timeout;

stl/inc/thread

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public:
124124
_Throw_Cpp_error(_RESOURCE_DEADLOCK_WOULD_OCCUR);
125125
}
126126

127-
if (_Thrd_join(_Thr, nullptr) != _Thrd_success) {
127+
if (_Thrd_join(_Thr, nullptr) != _Thrd_result::_Success) {
128128
_Throw_Cpp_error(_NO_SUCH_PROCESS);
129129
}
130130

@@ -136,7 +136,7 @@ public:
136136
_Throw_Cpp_error(_INVALID_ARGUMENT);
137137
}
138138

139-
if (_Thrd_detach(_Thr) != _Thrd_success) {
139+
if (_Thrd_detach(_Thr) != _Thrd_result::_Success) {
140140
_Throw_Cpp_error(_INVALID_ARGUMENT);
141141
}
142142

stl/inc/xthreads.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ struct _Cnd_internal_imp_t;
8686
using _Cnd_t = _Cnd_internal_imp_t*;
8787
#endif // ^^^ !defined(_M_CEE) ^^^
8888

89-
enum { _Thrd_success, _Thrd_nomem, _Thrd_timedout, _Thrd_busy, _Thrd_error };
89+
enum class _Thrd_result : int { _Success, _Nomem, _Timedout, _Busy, _Error };
9090

9191
// threads
92-
_CRTIMP2_PURE int __cdecl _Thrd_detach(_Thrd_t);
93-
_CRTIMP2_PURE int __cdecl _Thrd_join(_Thrd_t, int*);
92+
_CRTIMP2_PURE _Thrd_result __cdecl _Thrd_detach(_Thrd_t);
93+
_CRTIMP2_PURE _Thrd_result __cdecl _Thrd_join(_Thrd_t, int*);
9494
_CRTIMP2_PURE void __cdecl _Thrd_sleep(const _timespec64*);
9595
_CRTIMP2_PURE void __cdecl _Thrd_yield();
9696
_CRTIMP2_PURE unsigned int __cdecl _Thrd_hardware_concurrency();
@@ -104,15 +104,15 @@ enum { // mutex types
104104
_Mtx_recursive = 0x100
105105
};
106106

107-
_CRTIMP2_PURE int __cdecl _Mtx_init(_Mtx_t*, int);
107+
_CRTIMP2_PURE _Thrd_result __cdecl _Mtx_init(_Mtx_t*, int);
108108
_CRTIMP2_PURE void __cdecl _Mtx_destroy(_Mtx_t);
109109
_CRTIMP2_PURE void __cdecl _Mtx_init_in_situ(_Mtx_t, int);
110110
_CRTIMP2_PURE void __cdecl _Mtx_destroy_in_situ(_Mtx_t);
111111
_CRTIMP2_PURE int __cdecl _Mtx_current_owns(_Mtx_t);
112-
_CRTIMP2_PURE int __cdecl _Mtx_lock(_Mtx_t);
113-
_CRTIMP2_PURE int __cdecl _Mtx_trylock(_Mtx_t);
114-
_CRTIMP2_PURE int __cdecl _Mtx_timedlock(_Mtx_t, const _timespec64*);
115-
_CRTIMP2_PURE int __cdecl _Mtx_unlock(_Mtx_t); // TRANSITION, ABI: always returns _Thrd_success
112+
_CRTIMP2_PURE _Thrd_result __cdecl _Mtx_lock(_Mtx_t);
113+
_CRTIMP2_PURE _Thrd_result __cdecl _Mtx_trylock(_Mtx_t);
114+
_CRTIMP2_PURE _Thrd_result __cdecl _Mtx_timedlock(_Mtx_t, const _timespec64*);
115+
_CRTIMP2_PURE _Thrd_result __cdecl _Mtx_unlock(_Mtx_t); // TRANSITION, ABI: Always succeeds
116116

117117
_CRTIMP2_PURE void* __cdecl _Mtx_getconcrtcs(_Mtx_t);
118118
_CRTIMP2_PURE void __cdecl _Mtx_clear_owner(_Mtx_t);
@@ -128,14 +128,14 @@ void __cdecl _Smtx_unlock_exclusive(_Smtx_t*);
128128
void __cdecl _Smtx_unlock_shared(_Smtx_t*);
129129

130130
// condition variables
131-
_CRTIMP2_PURE int __cdecl _Cnd_init(_Cnd_t*);
131+
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_init(_Cnd_t*);
132132
_CRTIMP2_PURE void __cdecl _Cnd_destroy(_Cnd_t);
133133
_CRTIMP2_PURE void __cdecl _Cnd_init_in_situ(_Cnd_t);
134134
_CRTIMP2_PURE void __cdecl _Cnd_destroy_in_situ(_Cnd_t);
135-
_CRTIMP2_PURE int __cdecl _Cnd_wait(_Cnd_t, _Mtx_t); // TRANSITION, ABI: Always returns _Thrd_success
136-
_CRTIMP2_PURE int __cdecl _Cnd_timedwait(_Cnd_t, _Mtx_t, const _timespec64*);
137-
_CRTIMP2_PURE int __cdecl _Cnd_broadcast(_Cnd_t); // TRANSITION, ABI: Always returns _Thrd_success
138-
_CRTIMP2_PURE int __cdecl _Cnd_signal(_Cnd_t); // TRANSITION, ABI: Always returns _Thrd_success
135+
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_wait(_Cnd_t, _Mtx_t); // TRANSITION, ABI: Always succeeds
136+
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait(_Cnd_t, _Mtx_t, const _timespec64*);
137+
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_broadcast(_Cnd_t); // TRANSITION, ABI: Always succeeds
138+
_CRTIMP2_PURE _Thrd_result __cdecl _Cnd_signal(_Cnd_t); // TRANSITION, ABI: Always succeeds
139139
_CRTIMP2_PURE void __cdecl _Cnd_register_at_thread_exit(_Cnd_t, _Mtx_t, int*);
140140
_CRTIMP2_PURE void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t);
141141
_CRTIMP2_PURE void __cdecl _Cnd_do_broadcast_at_thread_exit();

stl/src/cond.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ void _Cnd_init_in_situ(const _Cnd_t cond) { // initialize condition variable in
3030

3131
void _Cnd_destroy_in_situ(_Cnd_t) {} // destroy condition variable in situ
3232

33-
int _Cnd_init(_Cnd_t* const pcond) { // initialize
33+
_Thrd_result _Cnd_init(_Cnd_t* const pcond) { // initialize
3434
*pcond = nullptr;
3535

3636
const auto cond = static_cast<_Cnd_t>(_calloc_crt(1, sizeof(_Cnd_internal_imp_t)));
3737
if (cond == nullptr) {
38-
return _Thrd_nomem; // report alloc failed
38+
return _Thrd_result::_Nomem; // report alloc failed
3939
}
4040

4141
_Cnd_init_in_situ(cond);
4242
*pcond = cond;
43-
return _Thrd_success;
43+
return _Thrd_result::_Success;
4444
}
4545

4646
void _Cnd_destroy(const _Cnd_t cond) { // clean up
@@ -50,18 +50,18 @@ void _Cnd_destroy(const _Cnd_t cond) { // clean up
5050
}
5151
}
5252

53-
int _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) { // wait until signaled
53+
_Thrd_result _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) { // wait until signaled
5454
const auto cs = &mtx->_Critical_section;
5555
_Mtx_clear_owner(mtx);
5656
cond->_get_cv()->wait(cs);
5757
_Mtx_reset_owner(mtx);
58-
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success
58+
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
5959
}
6060

6161
// wait until signaled or timeout
62-
int _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const target) {
63-
int res = _Thrd_success;
64-
const auto cs = &mtx->_Critical_section;
62+
_Thrd_result _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const target) {
63+
_Thrd_result res = _Thrd_result::_Success;
64+
const auto cs = &mtx->_Critical_section;
6565
if (target == nullptr) { // no target time specified, wait on mutex
6666
_Mtx_clear_owner(mtx);
6767
cond->_get_cv()->wait(cs);
@@ -73,22 +73,22 @@ int _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const
7373
if (!cond->_get_cv()->wait_for(cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout
7474
_Timespec64_get_sys(&now);
7575
if (_Xtime_diff_to_millis2(target, &now) == 0) {
76-
res = _Thrd_timedout;
76+
res = _Thrd_result::_Timedout;
7777
}
7878
}
7979
_Mtx_reset_owner(mtx);
8080
}
8181
return res;
8282
}
8383

84-
int _Cnd_signal(const _Cnd_t cond) { // release one waiting thread
84+
_Thrd_result _Cnd_signal(const _Cnd_t cond) { // release one waiting thread
8585
cond->_get_cv()->notify_one();
86-
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success
86+
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
8787
}
8888

89-
int _Cnd_broadcast(const _Cnd_t cond) { // release all waiting threads
89+
_Thrd_result _Cnd_broadcast(const _Cnd_t cond) { // release all waiting threads
9090
cond->_get_cv()->notify_all();
91-
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success
91+
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
9292
}
9393

9494
/*

stl/src/cthread.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,29 @@ _EXTERN_C
4747
}
4848

4949
// TRANSITION, ABI: _Thrd_start() is preserved for binary compatibility
50-
_CRTIMP2_PURE int _Thrd_start(_Thrd_t* thr, _Thrd_callback_t func, void* b) { // start a thread
50+
_CRTIMP2_PURE _Thrd_result _Thrd_start(_Thrd_t* thr, _Thrd_callback_t func, void* b) { // start a thread
5151
thr->_Hnd = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, func, b, 0, &thr->_Id));
52-
return thr->_Hnd == nullptr ? _Thrd_error : _Thrd_success;
52+
return thr->_Hnd == nullptr ? _Thrd_result::_Error : _Thrd_result::_Success;
5353
}
5454

55-
int _Thrd_join(_Thrd_t thr, int* code) { // returns when thread terminates
55+
_Thrd_result _Thrd_join(_Thrd_t thr, int* code) { // returns when thread terminates
5656
if (WaitForSingleObjectEx(thr._Hnd, INFINITE, FALSE) == WAIT_FAILED) {
57-
return _Thrd_error;
57+
return _Thrd_result::_Error;
5858
}
5959

6060
if (code) { // TRANSITION, ABI: code is preserved for binary compatibility
6161
unsigned long res;
6262
if (!GetExitCodeThread(thr._Hnd, &res)) {
63-
return _Thrd_error;
63+
return _Thrd_result::_Error;
6464
}
6565
*code = static_cast<int>(res);
6666
}
6767

68-
return CloseHandle(thr._Hnd) ? _Thrd_success : _Thrd_error;
68+
return CloseHandle(thr._Hnd) ? _Thrd_result::_Success : _Thrd_result::_Error;
6969
}
7070

71-
int _Thrd_detach(_Thrd_t thr) { // tell OS to release thread's resources when it terminates
72-
return CloseHandle(thr._Hnd) ? _Thrd_success : _Thrd_error;
71+
_Thrd_result _Thrd_detach(_Thrd_t thr) { // tell OS to release thread's resources when it terminates
72+
return CloseHandle(thr._Hnd) ? _Thrd_result::_Success : _Thrd_result::_Error;
7373
}
7474

7575
void _Thrd_sleep(const _timespec64* xt) { // suspend thread until time xt
@@ -109,8 +109,8 @@ unsigned int _Thrd_hardware_concurrency() { // return number of processors
109109
}
110110

111111
// TRANSITION, ABI: _Thrd_create() is preserved for binary compatibility
112-
_CRTIMP2_PURE int _Thrd_create(_Thrd_t* thr, _Thrd_start_t func, void* d) { // create thread
113-
int res;
112+
_CRTIMP2_PURE _Thrd_result _Thrd_create(_Thrd_t* thr, _Thrd_start_t func, void* d) { // create thread
113+
_Thrd_result res;
114114
_Thrd_binder b;
115115
int started = 0;
116116
_Cnd_t cond;
@@ -123,7 +123,7 @@ _CRTIMP2_PURE int _Thrd_create(_Thrd_t* thr, _Thrd_start_t func, void* d) { // c
123123
b.mtx = &mtx;
124124
b.started = &started;
125125
_Mtx_lock(mtx);
126-
if ((res = _Thrd_start(thr, _Thrd_runner, &b)) == _Thrd_success) { // wait for handshake
126+
if ((res = _Thrd_start(thr, _Thrd_runner, &b)) == _Thrd_result::_Success) { // wait for handshake
127127
while (!started) {
128128
_Cnd_wait(cond, mtx);
129129
}

stl/src/mutex.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,19 @@ void _Mtx_destroy_in_situ(_Mtx_t mtx) { // destroy mutex in situ
5454
(void) mtx;
5555
}
5656

57-
int _Mtx_init(_Mtx_t* mtx, int type) { // initialize mutex
57+
_Thrd_result _Mtx_init(_Mtx_t* mtx, int type) { // initialize mutex
5858
*mtx = nullptr;
5959

6060
_Mtx_t mutex = static_cast<_Mtx_t>(_calloc_crt(1, sizeof(_Mtx_internal_imp_t)));
6161

6262
if (mutex == nullptr) {
63-
return _Thrd_nomem; // report alloc failed
63+
return _Thrd_result::_Nomem; // report alloc failed
6464
}
6565

6666
_Mtx_init_in_situ(mutex, type);
6767

6868
*mtx = mutex;
69-
return _Thrd_success;
69+
return _Thrd_result::_Success;
7070
}
7171

7272
void _Mtx_destroy(_Mtx_t mtx) { // destroy mutex
@@ -76,15 +76,15 @@ void _Mtx_destroy(_Mtx_t mtx) { // destroy mutex
7676
}
7777
}
7878

79-
static int mtx_do_lock(_Mtx_t mtx, const _timespec64* target) { // lock mutex
79+
static _Thrd_result mtx_do_lock(_Mtx_t mtx, const _timespec64* target) { // lock mutex
8080
if ((mtx->_Type & ~_Mtx_recursive) == _Mtx_plain) { // set the lock
8181
if (mtx->_Thread_id != static_cast<long>(GetCurrentThreadId())) { // not current thread, do lock
8282
AcquireSRWLockExclusive(get_srw_lock(mtx));
8383
mtx->_Thread_id = static_cast<long>(GetCurrentThreadId());
8484
}
8585
++mtx->_Count;
8686

87-
return _Thrd_success;
87+
return _Thrd_result::_Success;
8888
} else { // handle timed or recursive mutex
8989
int res = WAIT_TIMEOUT;
9090
if (target == nullptr) { // no target --> plain wait (i.e. infinite timeout)
@@ -137,22 +137,22 @@ static int mtx_do_lock(_Mtx_t mtx, const _timespec64* target) { // lock mutex
137137
switch (res) {
138138
case WAIT_OBJECT_0:
139139
case WAIT_ABANDONED:
140-
return _Thrd_success;
140+
return _Thrd_result::_Success;
141141

142142
case WAIT_TIMEOUT:
143143
if (target == nullptr || (target->tv_sec == 0 && target->tv_nsec == 0)) {
144-
return _Thrd_busy;
144+
return _Thrd_result::_Busy;
145145
} else {
146-
return _Thrd_timedout;
146+
return _Thrd_result::_Timedout;
147147
}
148148

149149
default:
150-
return _Thrd_error;
150+
return _Thrd_result::_Error;
151151
}
152152
}
153153
}
154154

155-
int _Mtx_unlock(_Mtx_t mtx) { // unlock mutex
155+
_Thrd_result _Mtx_unlock(_Mtx_t mtx) { // unlock mutex
156156
_THREAD_ASSERT(
157157
1 <= mtx->_Count && mtx->_Thread_id == static_cast<long>(GetCurrentThreadId()), "unlock of unowned mutex");
158158

@@ -163,27 +163,27 @@ int _Mtx_unlock(_Mtx_t mtx) { // unlock mutex
163163
_Analysis_assume_lock_held_(*srw_lock);
164164
ReleaseSRWLockExclusive(srw_lock);
165165
}
166-
return _Thrd_success; // TRANSITION, ABI: always returns _Thrd_success
166+
return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds
167167
}
168168

169-
int _Mtx_lock(_Mtx_t mtx) { // lock mutex
169+
_Thrd_result _Mtx_lock(_Mtx_t mtx) { // lock mutex
170170
return mtx_do_lock(mtx, nullptr);
171171
}
172172

173-
int _Mtx_trylock(_Mtx_t mtx) { // attempt to lock try_mutex
173+
_Thrd_result _Mtx_trylock(_Mtx_t mtx) { // attempt to lock try_mutex
174174
_timespec64 xt;
175175
_THREAD_ASSERT((mtx->_Type & (_Mtx_try | _Mtx_timed)) != 0, "trylock not supported by mutex");
176176
xt.tv_sec = 0;
177177
xt.tv_nsec = 0;
178178
return mtx_do_lock(mtx, &xt);
179179
}
180180

181-
int _Mtx_timedlock(_Mtx_t mtx, const _timespec64* xt) { // attempt to lock timed mutex
182-
int res;
181+
_Thrd_result _Mtx_timedlock(_Mtx_t mtx, const _timespec64* xt) { // attempt to lock timed mutex
182+
_Thrd_result res;
183183

184184
_THREAD_ASSERT((mtx->_Type & _Mtx_timed) != 0, "timedlock not supported by mutex");
185185
res = mtx_do_lock(mtx, xt);
186-
return res == _Thrd_busy ? _Thrd_timedout : res;
186+
return res == _Thrd_result::_Busy ? _Thrd_result::_Timedout : res;
187187
}
188188

189189
int _Mtx_current_owns(_Mtx_t mtx) { // test if current thread owns mutex

stl/src/thread0.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ static constexpr errc codes[] = {
3737

3838
// TRANSITION, ABI: preserved for binary compatibility
3939
[[noreturn]] _CRTIMP2_PURE void __cdecl _Throw_C_error(int code) { // throw error object for C error
40-
switch (code) { // select the exception
41-
case _Thrd_nomem:
42-
case _Thrd_timedout:
40+
switch (static_cast<_Thrd_result>(code)) { // select the exception
41+
case _Thrd_result::_Nomem:
42+
case _Thrd_result::_Timedout:
4343
_Throw_Cpp_error(_RESOURCE_UNAVAILABLE_TRY_AGAIN);
4444

45-
case _Thrd_busy:
45+
case _Thrd_result::_Busy:
4646
_Throw_Cpp_error(_DEVICE_OR_RESOURCE_BUSY);
4747

48-
case _Thrd_error:
48+
case _Thrd_result::_Error:
4949
_Throw_Cpp_error(_INVALID_ARGUMENT);
5050

5151
default:

0 commit comments

Comments
 (0)