net/usrsock: Add mutual exclusion so that only user can perform a socket request

This commit is contained in:
zhangyuan7 2019-03-19 09:23:08 -06:00 committed by Gregory Nutt
parent 6e69dba341
commit b161682adc
2 changed files with 18 additions and 0 deletions

View File

@ -100,6 +100,7 @@ struct usrsock_conn_s
struct struct
{ {
sem_t sem; /* Request semaphore (only one outstanding request) */
uint8_t xid; /* Expected message exchange id */ uint8_t xid; /* Expected message exchange id */
bool inprogress; /* Request was received but daemon is still processing */ bool inprogress; /* Request was received but daemon is still processing */
uint16_t valuelen; /* Length of value from daemon */ uint16_t valuelen; /* Length of value from daemon */
@ -127,6 +128,7 @@ struct usrsock_reqstate_s
sem_t recvsem; /* Semaphore signals recv completion */ sem_t recvsem; /* Semaphore signals recv completion */
int result; /* OK on success, otherwise a negated errno. */ int result; /* OK on success, otherwise a negated errno. */
bool completed; bool completed;
bool unlock; /* True: unlock is required */
}; };
struct usrsock_data_reqstate_s struct usrsock_data_reqstate_s

View File

@ -131,6 +131,7 @@ FAR struct usrsock_conn_s *usrsock_alloc(void)
/* Make sure that the connection is marked as uninitialized */ /* Make sure that the connection is marked as uninitialized */
memset(conn, 0, sizeof(*conn)); memset(conn, 0, sizeof(*conn));
nxsem_init(&conn->resp.sem, 0, 1);
conn->dev = NULL; conn->dev = NULL;
conn->usockid = -1; conn->usockid = -1;
conn->state = USRSOCK_CONN_STATE_UNINITIALIZED; conn->state = USRSOCK_CONN_STATE_UNINITIALIZED;
@ -169,6 +170,7 @@ void usrsock_free(FAR struct usrsock_conn_s *conn)
/* Reset structure */ /* Reset structure */
nxsem_destroy(&conn->resp.sem);
memset(conn, 0, sizeof(*conn)); memset(conn, 0, sizeof(*conn));
conn->dev = NULL; conn->dev = NULL;
conn->usockid = -1; conn->usockid = -1;
@ -259,12 +261,21 @@ int usrsock_setup_request_callback(FAR struct usrsock_conn_s *conn,
pstate->conn = conn; pstate->conn = conn;
pstate->result = -EAGAIN; pstate->result = -EAGAIN;
pstate->completed = false; pstate->completed = false;
pstate->unlock = false;
/* Set up the callback in the connection */ /* Set up the callback in the connection */
pstate->cb = devif_callback_alloc(NULL, &conn->list); pstate->cb = devif_callback_alloc(NULL, &conn->list);
if (pstate->cb) 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 */ /* Set up the connection event handler */
pstate->cb->flags = flags; 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; FAR struct usrsock_conn_s *conn = pstate->conn;
if (pstate->unlock)
{
_usrsock_semgive(&conn->resp.sem);
}
/* Make sure that no further events are processed */ /* Make sure that no further events are processed */
devif_conn_callback_free(NULL, pstate->cb, &conn->list); devif_conn_callback_free(NULL, pstate->cb, &conn->list);