summaryrefslogtreecommitdiff
path: root/Documentation/sensor_driver_requirements.rst
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-04-11 20:12:40 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-04-12 22:16:56 +0300
commit05b80226010bef5d296ed8331a0582a6e045a4ae (patch)
tree85feaa29f9fc331852c50199fe0cd275066f3151 /Documentation/sensor_driver_requirements.rst
parent9b2544d3df481bc9dd0795fb645b544ba6484216 (diff)
test: threads: Fix memory leak
The last instance of Thread allocated in the test is never deleted, nor are other instances deleted in error paths. Use a std::unique_ptr<> to ensure deletion. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Tested-by: Sebastian Fricke <sebastian.fricke@posteo.net>
Diffstat (limited to 'Documentation/sensor_driver_requirements.rst')
0 files changed, 0 insertions, 0 deletions
' href='#n193'>193 194 195 196 197 198 199 200 201 202 203
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * object-invoke.cpp - Cross-thread Object method invocation test
 */

#include <iostream>
#include <thread>

#include <libcamera/base/event_dispatcher.h>
#include <libcamera/base/object.h>
#include <libcamera/base/thread.h>

#include "test.h"

using namespace std;
using namespace libcamera;

class InvokedObject : public Object
{
public:
	enum Status {
		NoCall,
		InvalidThread,
		CallReceived,
	};

	InvokedObject()
		: status_(NoCall)
	{
	}

	Status status() const { return status_; }
	int value() const { return value_; }
	void reset()
	{
		status_ = NoCall;
		value_ = 0;
	}

	void method(int value)
	{
		if (Thread::current() != thread())
			status_ = InvalidThread;
		else
			status_ = CallReceived;

		value_ = value;
	}

	void methodWithReference([[maybe_unused]] const int &value)
	{
	}

	int methodWithReturn()
	{
		return 42;
	}

private:
	Status status_;
	int value_;
};

class ObjectInvokeTest : public Test
{
protected:
	int run()
	{
		EventDispatcher *dispatcher = Thread::current()->eventDispatcher();

		/*
		 * Test that queued method invocation in the same thread goes
		 * through the event dispatcher.
		 */
		object_.invokeMethod(&InvokedObject::method,
				     ConnectionTypeQueued, 42);

		if (object_.status() != InvokedObject::NoCall) {
			cerr << "Method not invoked asynchronously" << endl;
			return TestFail;
		}

		dispatcher->processEvents();

		switch (object_.status()) {
		case InvokedObject::NoCall:
			cout << "Method not invoked for main thread" << endl;
			return TestFail;
		case InvokedObject::InvalidThread:
			cout << "Method invoked in incorrect thread for main thread" << endl;
			return TestFail;
		default:
			break;
		}

		if (object_.value() != 42) {
			cout << "Method invoked with incorrect value for main thread" << endl;
			return TestFail;
		}

		/*
		 * Test that blocking invocation is delivered directly when the
		 * caller and callee live in the same thread.
		 */
		object_.reset();

		object_.invokeMethod(&InvokedObject::method,
				     ConnectionTypeBlocking, 42);

		switch (object_.status()) {
		case InvokedObject::NoCall:
			cout << "Method not invoked for main thread (blocking)" << endl;
			return TestFail;
		case InvokedObject::InvalidThread:
			cout << "Method invoked in incorrect thread for main thread (blocking)" << endl;
			return TestFail;
		default:
			break;
		}

		/*
		 * Move the object to a thread and verify that auto method
		 * invocation is delivered in the correct thread.
		 */
		object_.reset();
		object_.moveToThread(&thread_);

		thread_.start();

		object_.invokeMethod(&InvokedObject::method,
				     ConnectionTypeBlocking, 42);

		switch (object_.status()) {
		case InvokedObject::NoCall:
			cout << "Method not invoked for custom thread" << endl;
			return TestFail;
		case InvokedObject::InvalidThread:
			cout << "Method invoked in incorrect thread for custom thread" << endl;
			return TestFail;
		default:
			break;
		}

		if (object_.value() != 42) {
			cout << "Method invoked with incorrect value for custom thread" << endl;
			return TestFail;
		}

		/* Test that direct method invocation bypasses threads. */
		object_.reset();