Test that the EventDispatcher::interrupt() function correctly interrupts the processEvents() function, both when called before processEvents() and when called while it is running. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
103 lines
2 KiB
C++
103 lines
2 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2019, Google Inc.
|
|
*
|
|
* event-dispatcher.cpp - Event dispatcher test
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <signal.h>
|
|
#include <sys/time.h>
|
|
|
|
#include <libcamera/camera_manager.h>
|
|
#include <libcamera/event_dispatcher.h>
|
|
#include <libcamera/timer.h>
|
|
|
|
#include "test.h"
|
|
|
|
using namespace std;
|
|
using namespace libcamera;
|
|
|
|
static EventDispatcher *dispatcher;
|
|
static bool interrupt;
|
|
|
|
class EventDispatcherTest : public Test
|
|
{
|
|
protected:
|
|
static void sigAlarmHandler(int)
|
|
{
|
|
cout << "SIGALARM received" << endl;
|
|
if (interrupt)
|
|
dispatcher->interrupt();
|
|
}
|
|
|
|
int init()
|
|
{
|
|
dispatcher = CameraManager::instance()->eventDispatcher();
|
|
|
|
struct sigaction sa = {};
|
|
sa.sa_handler = &sigAlarmHandler;
|
|
sigaction(SIGALRM, &sa, nullptr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int run()
|
|
{
|
|
Timer timer;
|
|
|
|
/* Event processing interruption by signal. */
|
|
struct timespec start;
|
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
|
|
|
timer.start(1000);
|
|
|
|
struct itimerval itimer = {};
|
|
itimer.it_value.tv_usec = 500000;
|
|
interrupt = false;
|
|
setitimer(ITIMER_REAL, &itimer, nullptr);
|
|
|
|
dispatcher->processEvents();
|
|
|
|
struct timespec stop;
|
|
clock_gettime(CLOCK_MONOTONIC, &stop);
|
|
int duration = (stop.tv_sec - start.tv_sec) * 1000;
|
|
duration += (stop.tv_nsec - start.tv_nsec) / 1000000;
|
|
|
|
if (abs(duration - 1000) > 50) {
|
|
cout << "Event processing restart test failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
/* Event processing interruption. */
|
|
timer.start(1000);
|
|
dispatcher->interrupt();
|
|
|
|
dispatcher->processEvents();
|
|
|
|
if (!timer.isRunning()) {
|
|
cout << "Event processing immediate interruption failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
timer.start(1000);
|
|
itimer.it_value.tv_usec = 500000;
|
|
interrupt = true;
|
|
setitimer(ITIMER_REAL, &itimer, nullptr);
|
|
|
|
dispatcher->processEvents();
|
|
|
|
if (!timer.isRunning()) {
|
|
cout << "Event processing delayed interruption failed" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
return TestPass;
|
|
}
|
|
|
|
void cleanup()
|
|
{
|
|
}
|
|
};
|
|
|
|
TEST_REGISTER(EventDispatcherTest)
|