Skip to content

Commit 8456b70

Browse files
committed
test/gthr_call_once_exceptional: New test
1 parent 9fdb661 commit 8456b70

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ test_src = [
111111
'test/thread_join_deadlock.cpp', 'test/thread_ctor_throw.cpp', 'test/thread_id.cpp',
112112
'test/thread_decay_copy.cpp', 'test/this_thread_sleep_until.cpp',
113113
'test/this_thread_sleep_for.cpp', 'test/tls_dtor.cpp', 'test/tls_many.cpp',
114-
]
114+
'test/gthr_call_once_exceptional.cpp' ]
115115

116116
#===========================================================
117117
# Global configuration

test/gthr_call_once_exceptional.cpp

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/* This file is part of MCF Gthread.
2+
* Copyright (C) 2022-2025 LH_Mouse. All wrongs reserved.
3+
*
4+
* MCF Gthread is free software. Licensing information is included in
5+
* LICENSE.TXT as a whole. The GCC Runtime Library Exception applies
6+
* to this file. */
7+
8+
#if !defined __SEH__ && !defined _MSC_VER
9+
int
10+
main(void)
11+
{
12+
return 77;
13+
}
14+
#else // __SEH__
15+
16+
#include "../mcfgthread/cxx11.hpp"
17+
#include "../mcfgthread/sem.h"
18+
#include <assert.h>
19+
#include <stdio.h>
20+
#include <vector>
21+
22+
#ifdef TEST_STD
23+
# include <mutex>
24+
# include <thread>
25+
namespace NS = std;
26+
#else
27+
namespace NS = ::_MCF;
28+
#endif
29+
30+
constexpr std::size_t NTHREADS = 64U;
31+
static std::vector<NS::thread> threads(NTHREADS);
32+
static _MCF_once once;
33+
static ::_MCF_sem start = __MCF_SEM_INIT(NTHREADS);
34+
static int resource = 0;
35+
36+
static
37+
void
38+
once_do_it(void* add)
39+
{
40+
/* Perform initialization. */
41+
int old = resource;
42+
NS::this_thread::sleep_for(NS::chrono::milliseconds(20));
43+
resource = old + (int)(intptr_t) add;
44+
45+
NS::this_thread::sleep_for(NS::chrono::milliseconds(10));
46+
::fprintf(stderr, "thread %d done\n", (int) ::_MCF_thread_self_tid());
47+
throw 42;
48+
}
49+
50+
static
51+
void
52+
thread_proc()
53+
{
54+
::_MCF_sem_wait(&start, nullptr);
55+
56+
try {
57+
__MCF_GTHR_CALL_ONCE_SEH(&once, once_do_it, (void*) 1);
58+
::std::terminate();
59+
}
60+
catch(...) { }
61+
62+
::fprintf(stderr, "thread %d quitting\n", (int) ::_MCF_thread_self_tid());
63+
}
64+
65+
int
66+
main(void)
67+
{
68+
for(auto& thr : threads)
69+
thr = NS::thread(thread_proc);
70+
71+
::fprintf(stderr, "main waiting\n");
72+
::_MCF_sem_signal_some(&start, NTHREADS);
73+
74+
for(auto& thr : threads)
75+
thr.join();
76+
77+
assert(resource == NTHREADS);
78+
}
79+
80+
#endif // __SEH__

0 commit comments

Comments
 (0)