summaryrefslogtreecommitdiff
path: root/src/libcamera/event_notifier.cpp
blob: 6b0575c0db77b12b2009e266f0e17f1a436110f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * event_notifier.cpp - File descriptor event notifier
 */

#include "libcamera/internal/event_notifier.h"

#include <libcamera/camera_manager.h>

#include "libcamera/internal/event_dispatcher.h"
#include "libcamera/internal/message.h"
#include "libcamera/internal/thread.h"

/**
 * \file event_notifier.h
 * \brief File descriptor event notifier
 */

namespace libcamera {

/**
 * \class EventNotifier
 * \brief Notify of activity on a file descriptor
 *
 * The EventNotifier models a file descriptor event source that can be
 * monitored. It is created with the file descriptor to be monitored and the
 * type of event, and is enabled by default. It will emit the \ref activated
 * signal whenever an event of the monitored type occurs on the file descriptor.
 *
 * Supported type of events are EventNotifier::Read, EventNotifier::Write and
 * EventNotifier::Exception. The type is specified when constructing the
 * notifier, and can be retrieved using the type() function. To listen to
 * multiple event types on the same file descriptor multiple notifiers must be
 * created.
 *
 * The notifier can be disabled with the setEnabled() function. When the notifier
 * is disabled it ignores events and does not emit the \ref activated signal.
 * The notifier can then be re-enabled with the setEnabled() function.
 *
 * Creating multiple notifiers of the same type for the same file descriptor is
 * not allowed and results in undefined behaviour.
 *
 * Notifier events are detected and dispatched from the
 * EventDispatcher::processEvents() function.
 */

/**
 * \enum EventNotifier::Type
 * Type of file descriptor event to listen for.
 * \var EventNotifier::Read
 * Data is available to be read from the file descriptor
 * \var EventNotifier::Write
 * Data can be written to the file descriptor
 * \var EventNotifier::Exception
 * An exception has occurred on the file descriptor
 */

/**
 * \brief Construct an event notifier with a file descriptor and event type
 * \param[in] fd The file descriptor to monitor
 * \param[in] type The event type to monitor
 * \param[in] parent The parent Object
 */
EventNotifier::EventNotifier(int fd, Type type, Object *parent)
	: Object(parent), fd_(fd), type_(type), enabled_(false)
{
	setEnabled(true);
}

EventNotifier::~EventNotifier()
{
	setEnabled(false);
}

/**
 * \fn EventNotifier::type()
 * \brief Retrieve the type of the event being monitored
 * \return The type of the event
 */

/**
 * \fn EventNotifier::fd()
 * \brief Retrieve the file descriptor being monitored
 * \return The file descriptor
 */

/**
 * \fn EventNotifier::enabled()
 * \brief Retrieve the notifier state
 * \return True if the notifier is enabled, or false otherwise
 * \sa setEnabled()
 */

/**
 * \brief Enable or disable the notifier
 * \param[in] enable True to enable the notifier, false to disable it
 *
 * This function enables or disables the notifier. A disabled notifier ignores
 * events and does not emit the \ref activated signal.
 *
 * \context This function is \threadbound.
 */
void EventNotifier::setEnabled(bool enable)
{
	if (enabled_ == enable)
		return;

	enabled_ = enable;

	EventDispatcher *dispatcher = thread()->eventDispatcher();
	if (enable)
		dispatcher->registerEventNotifier(this);
	else
		dispatcher->unregisterEventNotifier(this);
}

/**
 * \var EventNotifier::activated
 * \brief Signal emitted when the event occurs
 *
 * This signal is emitted when the event \ref type() occurs on the file
 * descriptor monitored by the notifier. The notifier pointer is passed as a
 * parameter.
 */

void EventNotifier::message(Message *msg)
{
	if (msg->type() == Message::ThreadMoveMessage) {
		if (enabled_) {
			setEnabled(false);
			invokeMethod(&EventNotifier::setEnabled,
				     ConnectionTypeQueued, true);
		}
	}

	Object::message(msg);
}

} /* namespace libcamera */