[libcamera-devel,v3,06/11] libcamera: camera: Validate requests are completed in Running state
diff mbox series

Message ID 20210325134231.1400051-9-kieran.bingham@ideasonboard.com
State Accepted
Delegated to: Kieran Bingham
Headers show
Series
  • [libcamera-devel,v3,01/11] utils: ipc: proxy: Track IPA with a state machine
Related show

Commit Message

Kieran Bingham March 25, 2021, 1:42 p.m. UTC
All requests must have completed before the Camera has fully stopped.

Requests completing when the camera is not running represent an internal
pipeline handler bug.

Trap this event with a fatal error.

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/libcamera/camera.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Laurent Pinchart March 26, 2021, 2:10 a.m. UTC | #1
Hi Kieran,

Thank you for the patch.

On Thu, Mar 25, 2021 at 01:42:26PM +0000, Kieran Bingham wrote:
> All requests must have completed before the Camera has fully stopped.
> 
> Requests completing when the camera is not running represent an internal
> pipeline handler bug.
> 
> Trap this event with a fatal error.
> 
> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>  src/libcamera/camera.cpp | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
> index 84edbb8f494d..b86bff4745b2 100644
> --- a/src/libcamera/camera.cpp
> +++ b/src/libcamera/camera.cpp
> @@ -1062,11 +1062,11 @@ int Camera::stop()
>  
>  	LOG(Camera, Debug) << "Stopping capture";
>  
> -	d->setState(Private::CameraConfigured);
> -
>  	d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
>  			       this);
>  
> +	d->setState(Private::CameraConfigured);
> +
>  	return 0;
>  }
>  
> @@ -1079,6 +1079,13 @@ int Camera::stop()
>   */
>  void Camera::requestComplete(Request *request)
>  {
> +	Private *const d = LIBCAMERA_D_PTR();
> +
> +	/* Disconnected cameras are still able to complete requests. */
> +	int ret = d->isAccessAllowed(Private::CameraRunning);
> +	if (ret < 0 && ret != -ENODEV)

Would this work too ?

	if (d->isAccessAllowed(Private::CameraRunning, true) < 0)

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +		LOG(Camera, Fatal) << "Trying to complete a request when stopped";
> +
>  	requestCompleted.emit(request);
>  }
>
Kieran Bingham March 26, 2021, 3:18 p.m. UTC | #2
Hi Laurent,

On 26/03/2021 02:10, Laurent Pinchart wrote:
> Hi Kieran,
> 
> Thank you for the patch.
> 
> On Thu, Mar 25, 2021 at 01:42:26PM +0000, Kieran Bingham wrote:
>> All requests must have completed before the Camera has fully stopped.
>>
>> Requests completing when the camera is not running represent an internal
>> pipeline handler bug.
>>
>> Trap this event with a fatal error.
>>
>> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
>> ---
>>  src/libcamera/camera.cpp | 11 +++++++++--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
>> index 84edbb8f494d..b86bff4745b2 100644
>> --- a/src/libcamera/camera.cpp
>> +++ b/src/libcamera/camera.cpp
>> @@ -1062,11 +1062,11 @@ int Camera::stop()
>>  
>>  	LOG(Camera, Debug) << "Stopping capture";
>>  
>> -	d->setState(Private::CameraConfigured);
>> -
>>  	d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
>>  			       this);
>>  
>> +	d->setState(Private::CameraConfigured);
>> +
>>  	return 0;
>>  }
>>  
>> @@ -1079,6 +1079,13 @@ int Camera::stop()
>>   */
>>  void Camera::requestComplete(Request *request)
>>  {
>> +	Private *const d = LIBCAMERA_D_PTR();
>> +
>> +	/* Disconnected cameras are still able to complete requests. */
>> +	int ret = d->isAccessAllowed(Private::CameraRunning);
>> +	if (ret < 0 && ret != -ENODEV)
> 
> Would this work too ?
> 
> 	if (d->isAccessAllowed(Private::CameraRunning, true) < 0)
> 

Oh, I'd missed that there was an allowDisconnected parameter to
isAccessAllowed.

Yes, that's better.


> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> +		LOG(Camera, Fatal) << "Trying to complete a request when stopped";
>> +
>>  	requestCompleted.emit(request);
>>  }
>>  
>

Patch
diff mbox series

diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 84edbb8f494d..b86bff4745b2 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -1062,11 +1062,11 @@  int Camera::stop()
 
 	LOG(Camera, Debug) << "Stopping capture";
 
-	d->setState(Private::CameraConfigured);
-
 	d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
 			       this);
 
+	d->setState(Private::CameraConfigured);
+
 	return 0;
 }
 
@@ -1079,6 +1079,13 @@  int Camera::stop()
  */
 void Camera::requestComplete(Request *request)
 {
+	Private *const d = LIBCAMERA_D_PTR();
+
+	/* Disconnected cameras are still able to complete requests. */
+	int ret = d->isAccessAllowed(Private::CameraRunning);
+	if (ret < 0 && ret != -ENODEV)
+		LOG(Camera, Fatal) << "Trying to complete a request when stopped";
+
 	requestCompleted.emit(request);
 }