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>
This commit is contained in:
Laurent Pinchart 2022-10-04 02:42:28 +03:00
parent ca33225ceb
commit 036d26d667

View file

@ -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;
}