modem: modem_pipe: Avoid inconsequential open/close calls

This PR adds a mechanism to avoid calling open() or close()
on pipes which are already opened or closed respectively.

This optimization can help simplify backends implementing
the modem_pipe API by avoiding duplicated boilerplate code.

The TTY backend test suite has been updated to match the
new behavior.

Signed-off-by: Bjarki Arge Andreasen <bjarkix123@gmail.com>
This commit is contained in:
Bjarki Arge Andreasen 2023-09-29 11:35:39 +02:00 committed by Carles Cufí
commit 48a069204c
2 changed files with 32 additions and 5 deletions

View file

@ -31,8 +31,12 @@ int modem_pipe_open(struct modem_pipe *pipe)
int ret; int ret;
k_mutex_lock(&pipe->lock, K_FOREVER); k_mutex_lock(&pipe->lock, K_FOREVER);
ret = pipe->api->open(pipe->data); if (pipe->state == MODEM_PIPE_STATE_OPEN) {
k_mutex_unlock(&pipe->lock);
return 0;
}
ret = pipe->api->open(pipe->data);
if (ret < 0) { if (ret < 0) {
k_mutex_unlock(&pipe->lock); k_mutex_unlock(&pipe->lock);
return ret; return ret;
@ -54,6 +58,15 @@ int modem_pipe_open_async(struct modem_pipe *pipe)
int ret; int ret;
k_mutex_lock(&pipe->lock, K_FOREVER); k_mutex_lock(&pipe->lock, K_FOREVER);
if (pipe->state == MODEM_PIPE_STATE_OPEN) {
if (pipe->callback != NULL) {
pipe->callback(pipe, MODEM_PIPE_EVENT_OPENED, pipe->user_data);
}
k_mutex_unlock(&pipe->lock);
return 0;
}
ret = pipe->api->open(pipe->data); ret = pipe->api->open(pipe->data);
k_mutex_unlock(&pipe->lock); k_mutex_unlock(&pipe->lock);
return ret; return ret;
@ -118,6 +131,11 @@ int modem_pipe_close(struct modem_pipe *pipe)
int ret; int ret;
k_mutex_lock(&pipe->lock, K_FOREVER); k_mutex_lock(&pipe->lock, K_FOREVER);
if (pipe->state == MODEM_PIPE_STATE_CLOSED) {
k_mutex_unlock(&pipe->lock);
return 0;
}
ret = pipe->api->close(pipe->data); ret = pipe->api->close(pipe->data);
if (ret < 0) { if (ret < 0) {
k_mutex_unlock(&pipe->lock); k_mutex_unlock(&pipe->lock);
@ -140,6 +158,15 @@ int modem_pipe_close_async(struct modem_pipe *pipe)
int ret; int ret;
k_mutex_lock(&pipe->lock, K_FOREVER); k_mutex_lock(&pipe->lock, K_FOREVER);
if (pipe->state == MODEM_PIPE_STATE_CLOSED) {
if (pipe->callback != NULL) {
pipe->callback(pipe, MODEM_PIPE_EVENT_CLOSED, pipe->user_data);
}
k_mutex_unlock(&pipe->lock);
return 0;
}
ret = pipe->api->close(pipe->data); ret = pipe->api->close(pipe->data);
k_mutex_unlock(&pipe->lock); k_mutex_unlock(&pipe->lock);
return ret; return ret;

View file

@ -122,10 +122,10 @@ static void test_modem_backend_tty_teardown(void *f)
/*************************************************************************************************/ /*************************************************************************************************/
ZTEST(modem_backend_tty_suite, test_close_open) ZTEST(modem_backend_tty_suite, test_close_open)
{ {
zassert_true(modem_pipe_close(tty_pipe) == 0, "Failed to close pipe"); zassert_ok(modem_pipe_close(tty_pipe), "Failed to close pipe");
zassert_true(modem_pipe_close(tty_pipe) == -EALREADY, "Pipe should already be closed"); zassert_ok(modem_pipe_close(tty_pipe), "Pipe should already be closed");
zassert_true(modem_pipe_open(tty_pipe) == 0, "Failed to open pipe"); zassert_ok(modem_pipe_open(tty_pipe), "Failed to open pipe");
zassert_true(modem_pipe_open(tty_pipe) == -EALREADY, "Pipe should already be open"); zassert_ok(modem_pipe_open(tty_pipe), "Pipe should already be open");
} }
ZTEST(modem_backend_tty_suite, test_receive_ready_event_not_raised) ZTEST(modem_backend_tty_suite, test_receive_ready_event_not_raised)