summaryrefslogtreecommitdiff
path: root/Tests/LibC
diff options
context:
space:
mode:
authorTim Schumacher <timschumi@gmx.de>2022-07-19 14:52:30 +0200
committerBrian Gianforcaro <b.gianfo@gmail.com>2022-07-22 10:07:15 -0700
commit8ab1245e4a1f80a94bbc9d571fa33c99c808fd6e (patch)
tree5f27709023ca28346f96218c3d3b9a1fc2ea9154 /Tests/LibC
parentc85f307e6233397993e18b31d0034ed77bed73d9 (diff)
downloadserenity-8ab1245e4a1f80a94bbc9d571fa33c99c808fd6e.zip
Tests: Add a test for `pthread_cancel`
Diffstat (limited to 'Tests/LibC')
-rw-r--r--Tests/LibC/TestPthreadCancel.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/Tests/LibC/TestPthreadCancel.cpp b/Tests/LibC/TestPthreadCancel.cpp
index b60d76c47a..573def0f8a 100644
--- a/Tests/LibC/TestPthreadCancel.cpp
+++ b/Tests/LibC/TestPthreadCancel.cpp
@@ -6,6 +6,7 @@
#include <LibTest/TestCase.h>
#include <pthread.h>
+#include <unistd.h>
#define TEST_CASE_IN_PTHREAD(x) \
static void* __TESTCASE_FUNC(x##__inner)(void*); \
@@ -86,3 +87,40 @@ TEST_CASE_IN_PTHREAD(cancel_type_invalid)
return nullptr;
}
+
+static void cancel_clenaup_handler(void* data)
+{
+ (*static_cast<bool*>(data)) = true;
+}
+
+static void* cancel_inner(void* data)
+{
+ pthread_cleanup_push(cancel_clenaup_handler, data);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, nullptr);
+
+ // Sleep for a second until the other side sets up their end of the check,
+ // then do a call to write, which should be a cancellation point.
+ sleep(1);
+ write(STDOUT_FILENO, nullptr, 0);
+
+ pthread_exit(nullptr);
+}
+
+TEST_CASE(cancel)
+{
+ pthread_t thread;
+
+ bool called_cleanup_handler = false;
+ pthread_create(&thread, nullptr, cancel_inner, &called_cleanup_handler);
+
+ int rc = pthread_cancel(thread);
+
+ void* exit_code;
+ pthread_join(thread, &exit_code);
+
+ EXPECT_EQ(rc, 0);
+ EXPECT_EQ(called_cleanup_handler, true);
+ EXPECT_EQ(exit_code, PTHREAD_CANCELED);
+}