1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | // REQUIRES: linux && target=aarch64-{{.+}}-gnu |
11 | |
12 | // pthread_cancel in case of glibc calls _Unwind_ForcedUnwind from a signal on |
13 | // the child_thread. This test ensures sigreturn is handled correctly (see: |
14 | // UnwindCursor<A, R>::setInfoForSigReturn). |
15 | |
16 | #include <cstdlib> // defines __BIONIC__ |
17 | |
18 | // Android/Bionic does not support pthread_cancel. |
19 | #ifdef __BIONIC__ |
20 | int main() { |
21 | return 0; |
22 | } |
23 | #else |
24 | |
25 | #include <chrono> |
26 | #include <condition_variable> |
27 | #include <pthread.h> |
28 | #include <unistd.h> |
29 | |
30 | using namespace std::chrono_literals; |
31 | |
32 | std::condition_variable cv; |
33 | std::mutex cv_m; |
34 | bool thread_ready = false; |
35 | |
36 | static void* test(void* arg) { |
37 | (void)arg; |
38 | thread_ready = true; |
39 | cv.notify_all(); |
40 | |
41 | // This must be a pthread cancellation point. |
42 | while (1) |
43 | sleep(seconds: 100); |
44 | |
45 | return (void*)1; |
46 | } |
47 | |
48 | int main() { |
49 | pthread_t child_thread; |
50 | std::unique_lock<std::mutex> lk(cv_m); |
51 | pthread_create(newthread: &child_thread, attr: 0, start_routine: test, arg: (void*)0); |
52 | |
53 | if (!cv.wait_for(lock&: lk, rtime: 100ms, p: [] { return thread_ready; })) |
54 | return -1; |
55 | |
56 | pthread_cancel(th: child_thread); |
57 | pthread_join(th: child_thread, NULL); |
58 | return 0; |
59 | } |
60 | #endif |
61 | |