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:
parent
d7415bc4e4
commit
b0bf6b0aa9
2 changed files with 25 additions and 10 deletions
|
@ -348,6 +348,7 @@ public:
|
||||||
const std::set<Stream *> &streams);
|
const std::set<Stream *> &streams);
|
||||||
~Private();
|
~Private();
|
||||||
|
|
||||||
|
bool isRunning() const;
|
||||||
int isAccessAllowed(State state, bool allowDisconnected = false,
|
int isAccessAllowed(State state, bool allowDisconnected = false,
|
||||||
const char *from = __builtin_FUNCTION()) const;
|
const char *from = __builtin_FUNCTION()) const;
|
||||||
int isAccessAllowed(State low, State high,
|
int isAccessAllowed(State low, State high,
|
||||||
|
@ -389,6 +390,11 @@ static const char *const camera_state_names[] = {
|
||||||
"Running",
|
"Running",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool Camera::Private::isRunning() const
|
||||||
|
{
|
||||||
|
return state_.load(std::memory_order_acquire) == CameraRunning;
|
||||||
|
}
|
||||||
|
|
||||||
int Camera::Private::isAccessAllowed(State state, bool allowDisconnected,
|
int Camera::Private::isAccessAllowed(State state, bool allowDisconnected,
|
||||||
const char *from) const
|
const char *from) const
|
||||||
{
|
{
|
||||||
|
@ -1062,9 +1068,10 @@ int Camera::start(const ControlList *controls)
|
||||||
* This method stops capturing and processing requests immediately. All pending
|
* This method stops capturing and processing requests immediately. All pending
|
||||||
* requests are cancelled and complete synchronously in an error state.
|
* requests are cancelled and complete synchronously in an error state.
|
||||||
*
|
*
|
||||||
* \context This function may only be called when the camera is in the Running
|
* \context This function may be called in any camera state as defined in \ref
|
||||||
* state as defined in \ref camera_operation, and shall be synchronized by the
|
* camera_operation, and shall be synchronized by the caller with other
|
||||||
* caller with other functions that affect the camera state.
|
* 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
|
* \return 0 on success or a negative error code otherwise
|
||||||
* \retval -ENODEV The camera has been disconnected from the system
|
* \retval -ENODEV The camera has been disconnected from the system
|
||||||
|
@ -1074,6 +1081,13 @@ int Camera::stop()
|
||||||
{
|
{
|
||||||
Private *const d = LIBCAMERA_D_PTR();
|
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);
|
int ret = d->isAccessAllowed(Private::CameraRunning);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -41,13 +41,13 @@ protected:
|
||||||
if (camera_->queueRequest(&request) != -EACCES)
|
if (camera_->queueRequest(&request) != -EACCES)
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
if (camera_->stop() != -EACCES)
|
|
||||||
return TestFail;
|
|
||||||
|
|
||||||
/* Test operations which should pass. */
|
/* Test operations which should pass. */
|
||||||
if (camera_->release())
|
if (camera_->release())
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
|
if (camera_->stop())
|
||||||
|
return TestFail;
|
||||||
|
|
||||||
/* Test valid state transitions, end in Acquired state. */
|
/* Test valid state transitions, end in Acquired state. */
|
||||||
if (camera_->acquire())
|
if (camera_->acquire())
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
@ -71,7 +71,8 @@ protected:
|
||||||
if (camera_->queueRequest(&request) != -EACCES)
|
if (camera_->queueRequest(&request) != -EACCES)
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
if (camera_->stop() != -EACCES)
|
/* Test operations which should pass. */
|
||||||
|
if (camera_->stop())
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
/* Test valid state transitions, end in Configured state. */
|
/* Test valid state transitions, end in Configured state. */
|
||||||
|
@ -97,14 +98,14 @@ protected:
|
||||||
if (camera_->queueRequest(&request1) != -EACCES)
|
if (camera_->queueRequest(&request1) != -EACCES)
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
if (camera_->stop() != -EACCES)
|
|
||||||
return TestFail;
|
|
||||||
|
|
||||||
/* Test operations which should pass. */
|
/* Test operations which should pass. */
|
||||||
std::unique_ptr<Request> request2 = camera_->createRequest();
|
std::unique_ptr<Request> request2 = camera_->createRequest();
|
||||||
if (!request2)
|
if (!request2)
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
||||||
|
if (camera_->stop())
|
||||||
|
return TestFail;
|
||||||
|
|
||||||
/* Test valid state transitions, end in Running state. */
|
/* Test valid state transitions, end in Running state. */
|
||||||
if (camera_->release())
|
if (camera_->release())
|
||||||
return TestFail;
|
return TestFail;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue