[PATCH 1/4] libcamera: Add signal disconnected for IPC

Harvey Yang chenghaoyang at chromium.org
Fri Oct 18 09:57:34 CEST 2024


This CL also adds an API in Camera::Private to trigger
Camera::disconnected signal.

Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
Co-developed-by: Han-Lin Chen <hanlinchen at chromium.org>
Signed-off-by: Han-Lin Chen <hanlinchen at chromium.org>
---
 include/libcamera/internal/camera.h           |  2 ++
 .../libcamera/internal/ipc_pipe_unixsocket.h  |  2 ++
 include/libcamera/internal/ipc_unixsocket.h   |  2 ++
 src/libcamera/camera.cpp                      | 10 ++++++++
 src/libcamera/ipc_pipe_unixsocket.cpp         |  8 +++++++
 src/libcamera/ipc_unixsocket.cpp              | 24 +++++++++++++++++--
 .../module_ipa_proxy.cpp.tmpl                 |  8 +++++++
 .../module_ipa_proxy.h.tmpl                   |  2 ++
 8 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h
index 0add0428b..0bef0980e 100644
--- a/include/libcamera/internal/camera.h
+++ b/include/libcamera/internal/camera.h
@@ -33,6 +33,8 @@ public:
 
 	PipelineHandler *pipe() { return pipe_.get(); }
 
+	void notifyDisconnection();
+
 	std::list<Request *> queuedRequests_;
 	ControlInfoMap controlInfo_;
 	ControlList properties_;
diff --git a/include/libcamera/internal/ipc_pipe_unixsocket.h b/include/libcamera/internal/ipc_pipe_unixsocket.h
index 8c972613f..09f65b102 100644
--- a/include/libcamera/internal/ipc_pipe_unixsocket.h
+++ b/include/libcamera/internal/ipc_pipe_unixsocket.h
@@ -28,6 +28,8 @@ public:
 
 	int sendAsync(const IPCMessage &data) override;
 
+	Signal<> *disconnected();
+
 private:
 	struct CallData {
 		IPCUnixSocket::Payload *response;
diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h
index 48bb7a942..a1e326b6b 100644
--- a/include/libcamera/internal/ipc_unixsocket.h
+++ b/include/libcamera/internal/ipc_unixsocket.h
@@ -39,6 +39,8 @@ public:
 
 	Signal<> readyRead;
 
+	Signal<> disconnected;
+
 private:
 	struct Header {
 		uint32_t data;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index a86f552a4..ef5a6725f 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -603,6 +603,16 @@ Camera::Private::~Private()
  * \return The pipeline handler that created this camera
  */
 
+/**
+ * \brief Notify the application that camera is disconnected with signal
+ * Camera::disconnected
+ */
+void Camera::Private::notifyDisconnection()
+{
+	Camera *o = LIBCAMERA_O_PTR();
+	o->disconnected.emit();
+}
+
 /**
  * \fn Camera::Private::validator()
  * \brief Retrieve the control validator related to this camera
diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp
index 668ec73b9..51fd3b1fb 100644
--- a/src/libcamera/ipc_pipe_unixsocket.cpp
+++ b/src/libcamera/ipc_pipe_unixsocket.cpp
@@ -84,6 +84,14 @@ int IPCPipeUnixSocket::sendAsync(const IPCMessage &data)
 	return 0;
 }
 
+Signal<> *IPCPipeUnixSocket::disconnected()
+{
+	if (socket_)
+		return &socket_->disconnected;
+
+	return nullptr;
+}
+
 void IPCPipeUnixSocket::readyRead()
 {
 	IPCUnixSocket::Payload payload;
diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp
index 002053e35..3d0248857 100644
--- a/src/libcamera/ipc_unixsocket.cpp
+++ b/src/libcamera/ipc_unixsocket.cpp
@@ -186,11 +186,16 @@ int IPCUnixSocket::send(const Payload &payload)
 	if (!hdr.data && !hdr.fds)
 		return -EINVAL;
 
-	ret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);
+	ret = ::send(fd_.get(), &hdr, sizeof(hdr), MSG_NOSIGNAL);
 	if (ret < 0) {
 		ret = -errno;
 		LOG(IPCUnixSocket, Error)
 			<< "Failed to send: " << strerror(-ret);
+		if (errno == ECONNRESET) {
+			disconnected.emit();
+			fd_.reset();
+		}
+
 		return ret;
 	}
 
@@ -241,6 +246,11 @@ int IPCUnixSocket::receive(Payload *payload)
  * \brief A Signal emitted when a message is ready to be read
  */
 
+/**
+ * \var IPCUnixSocket::disconnected
+ * \brief A Signal emitted when the Unix socket IPC is disconnected
+ */
+
 int IPCUnixSocket::sendData(const void *buffer, size_t length,
 			    const int32_t *fds, unsigned int num)
 {
@@ -266,10 +276,15 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,
 	if (fds)
 		memcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));
 
-	if (sendmsg(fd_.get(), &msg, 0) < 0) {
+	if (sendmsg(fd_.get(), &msg, MSG_NOSIGNAL) < 0) {
 		int ret = -errno;
 		LOG(IPCUnixSocket, Error)
 			<< "Failed to sendmsg: " << strerror(-ret);
+		if (errno == ECONNRESET) {
+			disconnected.emit();
+			fd_.reset();
+		}
+
 		return ret;
 	}
 
@@ -324,6 +339,11 @@ void IPCUnixSocket::dataNotifier()
 			ret = -errno;
 			LOG(IPCUnixSocket, Error)
 				<< "Failed to receive header: " << strerror(-ret);
+			if (errno == ECONNRESET) {
+				disconnected.emit();
+				fd_.reset();
+			}
+
 			return;
 		}
 
diff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
index ce3cc5ab6..27f03417a 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl
@@ -104,6 +104,14 @@ namespace {{ns}} {
 	}
 }
 
+Signal<> *{{proxy_name}}::disconnected()
+{
+	if (ipc_)
+		return ipc_->disconnected();
+
+	return nullptr;
+}
+
 {% if interface_event.methods|length > 0 %}
 void {{proxy_name}}::recvMessage(const IPCMessage &data)
 {
diff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
index e213b18a0..2b7ba872e 100644
--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl
@@ -53,6 +53,8 @@ public:
 > {{method.mojom_name}};
 {% endfor %}
 
+	Signal<> *disconnected();
+
 private:
 	void recvMessage(const IPCMessage &data);
 
-- 
2.47.0.rc1.288.g06298d1525-goog



More information about the libcamera-devel mailing list