From b161682adc49442ce9c424513cb2763ee10896ba Mon Sep 17 00:00:00 2001 From: zhangyuan7 Date: Tue, 19 Mar 2019 09:23:08 -0600 Subject: [PATCH] net/usrsock: Add mutual exclusion so that only user can perform a socket request --- net/usrsock/usrsock.h | 2 ++ net/usrsock/usrsock_conn.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/net/usrsock/usrsock.h b/net/usrsock/usrsock.h index 44629a80f0..efb9268b45 100644 --- a/net/usrsock/usrsock.h +++ b/net/usrsock/usrsock.h @@ -100,6 +100,7 @@ struct usrsock_conn_s struct { + sem_t sem; /* Request semaphore (only one outstanding request) */ uint8_t xid; /* Expected message exchange id */ bool inprogress; /* Request was received but daemon is still processing */ uint16_t valuelen; /* Length of value from daemon */ @@ -127,6 +128,7 @@ struct usrsock_reqstate_s sem_t recvsem; /* Semaphore signals recv completion */ int result; /* OK on success, otherwise a negated errno. */ bool completed; + bool unlock; /* True: unlock is required */ }; struct usrsock_data_reqstate_s diff --git a/net/usrsock/usrsock_conn.c b/net/usrsock/usrsock_conn.c index cdc3c71660..a80251d509 100644 --- a/net/usrsock/usrsock_conn.c +++ b/net/usrsock/usrsock_conn.c @@ -131,6 +131,7 @@ FAR struct usrsock_conn_s *usrsock_alloc(void) /* Make sure that the connection is marked as uninitialized */ memset(conn, 0, sizeof(*conn)); + nxsem_init(&conn->resp.sem, 0, 1); conn->dev = NULL; conn->usockid = -1; conn->state = USRSOCK_CONN_STATE_UNINITIALIZED; @@ -169,6 +170,7 @@ void usrsock_free(FAR struct usrsock_conn_s *conn) /* Reset structure */ + nxsem_destroy(&conn->resp.sem); memset(conn, 0, sizeof(*conn)); conn->dev = NULL; conn->usockid = -1; @@ -259,12 +261,21 @@ int usrsock_setup_request_callback(FAR struct usrsock_conn_s *conn, pstate->conn = conn; pstate->result = -EAGAIN; pstate->completed = false; + pstate->unlock = false; /* Set up the callback in the connection */ pstate->cb = devif_callback_alloc(NULL, &conn->list); if (pstate->cb) { + /* Take a lock since only one outstanding request is allowed */ + + if ((flags & USRSOCK_EVENT_REQ_COMPLETE) != 0) + { + _usrsock_semtake(&conn->resp.sem); + pstate->unlock = true; + } + /* Set up the connection event handler */ pstate->cb->flags = flags; @@ -300,6 +311,11 @@ void usrsock_teardown_request_callback(FAR struct usrsock_reqstate_s *pstate) { FAR struct usrsock_conn_s *conn = pstate->conn; + if (pstate->unlock) + { + _usrsock_semgive(&conn->resp.sem); + } + /* Make sure that no further events are processed */ devif_conn_callback_free(NULL, pstate->cb, &conn->list);