libcamera: camera: Make stop() idempotent

Make Camera::stop() idempotent so that it can be called in any state and
consecutive times. When called in any state other than CameraRunning, it
is a no-op. This simplifies the cleanup path for applications.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Nícolas F. R. A. Prado
2021-07-02 09:21:10 -03:00
committed by Jacopo Mondi
parent d7415bc4e4
commit b0bf6b0aa9
2 changed files with 25 additions and 10 deletions

View File

@@ -348,6 +348,7 @@ public:
const std::set<Stream *> &streams);
~Private();
bool isRunning() const;
int isAccessAllowed(State state, bool allowDisconnected = false,
const char *from = __builtin_FUNCTION()) const;
int isAccessAllowed(State low, State high,
@@ -389,6 +390,11 @@ static const char *const camera_state_names[] = {
"Running",
};
bool Camera::Private::isRunning() const
{
return state_.load(std::memory_order_acquire) == CameraRunning;
}
int Camera::Private::isAccessAllowed(State state, bool allowDisconnected,
const char *from) const
{
@@ -1062,9 +1068,10 @@ int Camera::start(const ControlList *controls)
* This method stops capturing and processing requests immediately. All pending
* requests are cancelled and complete synchronously in an error state.
*
* \context This function may only be called when the camera is in the Running
* state as defined in \ref camera_operation, and shall be synchronized by the
* caller with other functions that affect the camera state.
* \context This function may be called in any camera state as defined in \ref
* camera_operation, and shall be synchronized by the caller with other
* functions that affect the camera state. If called when the camera isn't
* running, it is a no-op.
*
* \return 0 on success or a negative error code otherwise
* \retval -ENODEV The camera has been disconnected from the system
@@ -1074,6 +1081,13 @@ int Camera::stop()
{
Private *const d = LIBCAMERA_D_PTR();
/*
* \todo Make calling stop() when not in 'Running' part of the state
* machine rather than take this shortcut
*/
if (!d->isRunning())
return 0;
int ret = d->isAccessAllowed(Private::CameraRunning);
if (ret < 0)
return ret;