Skip to content

Commit

Permalink
Split read/write lock in remcons
Browse files Browse the repository at this point in the history
We do not want waiting for event to block output.
  • Loading branch information
Jiri Svoboda committed Oct 8, 2024
1 parent c7ecd29 commit 5f5d375
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 29 deletions.
18 changes: 9 additions & 9 deletions uspace/srv/hid/remcons/remcons.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,17 +539,17 @@ static errno_t spawn_task_fibril(void *arg)
telnet_user_error(user, "Spawning `%s %s /loc --msg -- %s' "
"failed: %s.", APP_GETTERM, user->service_name, APP_SHELL,
str_error(rc));
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
user->task_finished = true;
user->srvs.aborted = true;
fibril_condvar_signal(&user->refcount_cv);
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);
return EOK;
}

fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
user->task_id = task;
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);

task_exit_t task_exit;
int task_retval;
Expand All @@ -559,11 +559,11 @@ static errno_t spawn_task_fibril(void *arg)
task_retval);

/* Announce destruction. */
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
user->task_finished = true;
user->srvs.aborted = true;
fibril_condvar_signal(&user->refcount_cv);
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);

return EOK;
}
Expand Down Expand Up @@ -727,7 +727,7 @@ static void remcons_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
fibril_add_ready(spawn_fibril);

/* Wait for all clients to exit. */
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
while (!user_can_be_destroyed_no_lock(user)) {
if (user->task_finished) {
user->conn = NULL;
Expand All @@ -739,9 +739,9 @@ static void remcons_new_conn(tcp_listener_t *lst, tcp_conn_t *conn)
task_kill(user->task_id);
}
}
fibril_condvar_wait_timeout(&user->refcount_cv, &user->guard, 1000);
fibril_condvar_wait_timeout(&user->refcount_cv, &user->recv_lock, 1000);
}
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);

rc = loc_service_unregister(remcons_srv, user->service_id);
if (rc != EOK) {
Expand Down
37 changes: 19 additions & 18 deletions uspace/srv/hid/remcons/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ telnet_user_t *telnet_user_create(tcp_conn_t *conn, telnet_cb_t *cb, void *arg)
user->send_buf_used = 0;

fibril_condvar_initialize(&user->refcount_cv);
fibril_mutex_initialize(&user->guard);
fibril_mutex_initialize(&user->send_lock);
fibril_mutex_initialize(&user->recv_lock);
user->task_finished = false;
user->socket_closed = false;
user->locsrv_connection_count = 0;
Expand Down Expand Up @@ -150,7 +151,7 @@ telnet_user_t *telnet_user_get_for_client_connection(service_id_t id)
}

telnet_user_t *tmp = user;
fibril_mutex_lock(&tmp->guard);
fibril_mutex_lock(&tmp->recv_lock);
user->locsrv_connection_count++;

/*
Expand All @@ -162,7 +163,7 @@ telnet_user_t *telnet_user_get_for_client_connection(service_id_t id)
user->locsrv_connection_count--;
}

fibril_mutex_unlock(&tmp->guard);
fibril_mutex_unlock(&tmp->recv_lock);

fibril_mutex_unlock(&users_guard);

Expand All @@ -175,11 +176,11 @@ telnet_user_t *telnet_user_get_for_client_connection(service_id_t id)
*/
void telnet_user_notify_client_disconnected(telnet_user_t *user)
{
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
assert(user->locsrv_connection_count > 0);
user->locsrv_connection_count--;
fibril_condvar_signal(&user->refcount_cv);
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);
}

/** Tell whether the launched task already exited and socket is already closed.
Expand All @@ -188,9 +189,9 @@ void telnet_user_notify_client_disconnected(telnet_user_t *user)
*/
bool telnet_user_is_zombie(telnet_user_t *user)
{
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);
bool zombie = user->socket_closed || user->task_finished;
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);

return zombie;
}
Expand Down Expand Up @@ -400,7 +401,7 @@ errno_t telnet_user_recv(telnet_user_t *user, void *buf, size_t size,
size_t *nread)
{
uint8_t *bp = (uint8_t *)buf;
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->recv_lock);

assert(size > 0);
*nread = 0;
Expand All @@ -416,7 +417,7 @@ errno_t telnet_user_recv(telnet_user_t *user, void *buf, size_t size,
errno_t rc = telnet_user_recv_next_byte_locked(user,
&next_byte);
if (rc != EOK) {
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);
return rc;
}
uint8_t byte = next_byte;
Expand Down Expand Up @@ -452,7 +453,7 @@ errno_t telnet_user_recv(telnet_user_t *user, void *buf, size_t size,
}
} while (size > 0 && (telnet_user_byte_avail(user) || *nread == 0));

fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->recv_lock);
return EOK;
}

Expand Down Expand Up @@ -533,11 +534,11 @@ static errno_t telnet_user_send_data_locked(telnet_user_t *user,
errno_t telnet_user_send_data(telnet_user_t *user, const char *data,
size_t size)
{
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->send_lock);

errno_t rc = telnet_user_send_data_locked(user, data, size);

fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->send_lock);

return rc;
}
Expand All @@ -551,11 +552,11 @@ errno_t telnet_user_send_data(telnet_user_t *user, const char *data,
errno_t telnet_user_send_raw(telnet_user_t *user, const char *data,
size_t size)
{
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->send_lock);

errno_t rc = telnet_user_send_raw_locked(user, data, size);

fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->send_lock);

return rc;
}
Expand All @@ -576,9 +577,9 @@ errno_t telnet_user_flush(telnet_user_t *user)
{
errno_t rc;

fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->send_lock);
rc = telnet_user_flush_locked(user);
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->send_lock);
return rc;
}

Expand All @@ -591,14 +592,14 @@ errno_t telnet_user_flush(telnet_user_t *user)
*/
void telnet_user_update_cursor_x(telnet_user_t *user, int new_x)
{
fibril_mutex_lock(&user->guard);
fibril_mutex_lock(&user->send_lock);
if (user->cursor_x - 1 == new_x) {
char data = '\b';
/* Ignore errors. */
telnet_user_send_data_locked(user, &data, 1);
}
user->cursor_x = new_x;
fibril_mutex_unlock(&user->guard);
fibril_mutex_unlock(&user->send_lock);

}

Expand Down
6 changes: 4 additions & 2 deletions uspace/srv/hid/remcons/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ typedef struct {

/** Representation of a connected (human) user. */
typedef struct {
/** Mutex guarding the whole structure. */
fibril_mutex_t guard;
/** Synchronize send operations */
fibril_mutex_t send_lock;
/** Synchronize receive operations */
fibril_mutex_t recv_lock;
/** Callback functions */
telnet_cb_t *cb;
/** Argument to callback functions */
Expand Down

0 comments on commit 5f5d375

Please sign in to comment.