Many signals used in internal and public APIs carry the emitter pointer as a signal argument. This was done to allow slots connected to multiple signal instances to differentiate between emitters. While starting from a good intention of facilitating the implementation of slots, it turned out to be a bad API design as the signal isn't meant to know what it will be connected to, and thus shouldn't carry parameters that are solely meant to support a use case specific to the connected slot. These pointers turn out to be unused in all slots but one. In the only case where it is needed, it can be obtained by wrapping the slot in a lambda function when connecting the signal. Do so, and drop the emitter pointer from all signals. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
110 lines
2.1 KiB
C++
110 lines
2.1 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Copyright (C) 2019, Google Inc.
|
|
*
|
|
* process_test.cpp - Process test
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
#include <vector>
|
|
|
|
|
|
#include <libcamera/base/event_dispatcher.h>
|
|
#include <libcamera/base/thread.h>
|
|
#include <libcamera/base/timer.h>
|
|
#include <libcamera/base/utils.h>
|
|
|
|
#include "libcamera/internal/process.h"
|
|
|
|
#include "test.h"
|
|
|
|
using namespace std;
|
|
using namespace libcamera;
|
|
|
|
class ProcessTestChild
|
|
{
|
|
public:
|
|
int run(int status)
|
|
{
|
|
usleep(50000);
|
|
|
|
return status;
|
|
}
|
|
};
|
|
|
|
class ProcessTest : public Test
|
|
{
|
|
public:
|
|
ProcessTest()
|
|
: exitStatus_(Process::NotExited), exitCode_(-1)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
int run()
|
|
{
|
|
EventDispatcher *dispatcher = Thread::current()->eventDispatcher();
|
|
Timer timeout;
|
|
|
|
int exitCode = 42;
|
|
vector<std::string> args;
|
|
args.push_back(to_string(exitCode));
|
|
proc_.finished.connect(this, &ProcessTest::procFinished);
|
|
|
|
/* Test that kill() on an unstarted process is safe. */
|
|
proc_.kill();
|
|
|
|
/* Test starting the process and retrieving the exit code. */
|
|
int ret = proc_.start("/proc/self/exe", args);
|
|
if (ret) {
|
|
cerr << "failed to start process" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
timeout.start(2000);
|
|
while (timeout.isRunning() && exitStatus_ == Process::NotExited)
|
|
dispatcher->processEvents();
|
|
|
|
if (exitStatus_ != Process::NormalExit) {
|
|
cerr << "process did not exit normally" << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
if (exitCode != exitCode_) {
|
|
cerr << "exit code should be " << exitCode
|
|
<< ", actual is " << exitCode_ << endl;
|
|
return TestFail;
|
|
}
|
|
|
|
return TestPass;
|
|
}
|
|
|
|
private:
|
|
void procFinished(enum Process::ExitStatus exitStatus, int exitCode)
|
|
{
|
|
exitStatus_ = exitStatus;
|
|
exitCode_ = exitCode;
|
|
}
|
|
|
|
ProcessManager processManager_;
|
|
|
|
Process proc_;
|
|
enum Process::ExitStatus exitStatus_;
|
|
int exitCode_;
|
|
};
|
|
|
|
/*
|
|
* Can't use TEST_REGISTER() as single binary needs to act as both
|
|
* parent and child processes.
|
|
*/
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc == 2) {
|
|
int status = std::stoi(argv[1]);
|
|
ProcessTestChild child;
|
|
return child.run(status);
|
|
}
|
|
|
|
return ProcessTest().execute();
|
|
}
|