ipc: Reset waitframe semaphore when client disconnects

The semaphore was usually kept at a value of 1 after a client disconnected,
meaning the next client to connect was never blocked on it.
This commit is contained in:
Christoph Haag 2020-06-15 15:44:35 +02:00
parent cbb91904e9
commit 8141a3c761
3 changed files with 33 additions and 0 deletions

View file

@ -212,6 +212,15 @@ void
ipc_server_wait_add_frame(struct ipc_wait *iw,
volatile struct ipc_client_state *cs);
/*!
* Reset the wait state for wait frame, after the client disconnected
*
* @ingroup ipc_server
* @public @memberof ipc_wait
*/
void
ipc_server_wait_reset_client(struct ipc_wait *iw,
volatile struct ipc_client_state *cs);
#ifdef __cplusplus
}

View file

@ -454,6 +454,8 @@ client_loop(volatile struct ipc_client_state *cs)
if (cs->server->exit_on_disconnect) {
cs->server->running = false;
}
ipc_server_wait_reset_client(cs->server->iw, cs);
}

View file

@ -114,6 +114,28 @@ ipc_server_wait_add_frame(struct ipc_wait *iw,
os_thread_helper_unlock(&iw->oth);
}
void
ipc_server_wait_reset_client(struct ipc_wait *iw,
volatile struct ipc_client_state *cs)
{
os_thread_helper_lock(&iw->oth);
/* ipc_server_wait_add_frame would overwrite dangling references,
* but clean them up anyway to be less confusing. */
for (int i = 0; i < IPC_MAX_CLIENTS; i++) {
if (iw->cs[i] == cs) {
iw->cs[i] = NULL;
}
}
volatile struct ipc_shared_memory *ism = iw->s->ism;
sem_init((sem_t *)&ism->wait_frame.sem, true, 0);
ism->wait_frame.predicted_display_period = 0;
ism->wait_frame.predicted_display_time = 0;
os_thread_helper_unlock(&iw->oth);
}
void
ipc_server_wait_free(struct ipc_wait **out_iw)
{