diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-10-04 02:42:28 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-10-04 17:58:00 +0300 |
commit | 036d26d6677e0b8e6cf284c0801b267c5f81720e (patch) | |
tree | 84ccd3cd40a1af11c1e6e81f247a5b36f8537beb | |
parent | ca33225ceb4c7b414eb1a8579af14c2c06f1f4ea (diff) |
test: threads: Test thread cleanup upon abnormal termination
If a thread ends abnormally (that is, without retuning normally from its
run() function, for instance with a direct call to pthread_cancel()),
thread cleanup should still be performed. Add a test to ensure this.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
-rw-r--r-- | test/threads.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/test/threads.cpp b/test/threads.cpp index d83b5833..8f366c9d 100644 --- a/test/threads.cpp +++ b/test/threads.cpp @@ -8,7 +8,9 @@ #include <chrono> #include <iostream> #include <memory> +#include <pthread.h> #include <thread> +#include <time.h> #include <libcamera/base/thread.h> @@ -35,6 +37,35 @@ private: chrono::steady_clock::duration duration_; }; +class CancelThread : public Thread +{ +public: + CancelThread(bool &cancelled) + : cancelled_(cancelled) + { + } + +protected: + void run() + { + cancelled_ = true; + + /* + * Cancel the thread and call a guaranteed cancellation point + * (nanosleep). + */ + pthread_cancel(pthread_self()); + + struct timespec req{ 0, 100*000*000 }; + nanosleep(&req, nullptr); + + cancelled_ = false; + } + +private: + bool &cancelled_; +}; + class ThreadTest : public Test { protected: @@ -118,6 +149,22 @@ protected: return TestFail; } + /* Test thread cleanup upon abnormal termination. */ + bool cancelled = false; + bool finished = false; + + thread = std::make_unique<CancelThread>(cancelled); + thread->finished.connect(this, [&finished]() { finished = true; }); + + thread->start(); + thread->exit(0); + thread->wait(chrono::milliseconds(1000)); + + if (!cancelled || !finished) { + cout << "Cleanup failed upon abnormal termination" << endl; + return TestFail; + } + return TestPass; } |