diff options
author | dimitri staessens <[email protected]> | 2016-12-24 20:50:44 +0100 |
---|---|---|
committer | dimitri staessens <[email protected]> | 2016-12-24 21:33:46 +0100 |
commit | 23e29ee36bb032040bb5dab96e940f5348bcc0bf (patch) | |
tree | a6c5ca11997479f81ea0b9218082a9837c4ebc87 /src | |
parent | d937595df1211d6b575da8b7d135933f9a2987f8 (diff) | |
download | ouroboros-23e29ee36bb032040bb5dab96e940f5348bcc0bf.tar.gz ouroboros-23e29ee36bb032040bb5dab96e940f5348bcc0bf.zip |
lib: Fix shutdown in multithreaded programs
If a thread with a pending flow terminates, ap_fini would wait for the
condvar to destroy the flow indefinitely.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/dev.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/lib/dev.c b/src/lib/dev.c index 7aa27089..8eb98506 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -101,7 +101,7 @@ static void port_set_state(struct port * p, enum port_state state) pthread_mutex_unlock(&p->state_lock); } -enum port_state port_wait_assign(struct port * p) +static enum port_state port_wait_assign(struct port * p) { enum port_state state; @@ -112,7 +112,7 @@ enum port_state port_wait_assign(struct port * p) return -1; } - while (!(p->state == PORT_ID_ASSIGNED || p->state == PORT_DESTROY)) + while (p->state == PORT_ID_PENDING) pthread_cond_wait(&p->state_cond, &p->state_lock); if (p->state == PORT_DESTROY) { @@ -313,16 +313,17 @@ void ap_fini() pthread_rwlock_rdlock(&ai.flows_lock); for (i = 0; i < AP_MAX_FLOWS; ++i) { - if (ai.flows[i].rx_rb != NULL) { + if (ai.flows[i].port_id != -1) { ssize_t idx; while ((idx = shm_rbuff_read(ai.flows[i].rx_rb)) >= 0) shm_rdrbuff_remove(ai.rdrb, idx); + port_set_state(&ai.ports[ai.flows[i].port_id], + PORT_NULL); + reset_flow(i); } - reset_flow(i); } for (i = 0; i < IRMD_MAX_FLOWS; ++i) { - ai.ports[i].state = PORT_NULL; pthread_mutex_destroy(&ai.ports[i].state_lock); pthread_cond_destroy(&ai.ports[i].state_cond); } @@ -1287,7 +1288,6 @@ int ipcp_flow_req_arr(pid_t api, char * dst_name, char * src_ae_name) if (ai.flows[fd].tx_rb == NULL) { irm_msg__free_unpacked(recv_msg, NULL); reset_flow(fd); - port_destroy(&ai.ports[port_id]); pthread_rwlock_unlock(&ai.flows_lock); pthread_rwlock_unlock(&ai.data_lock); return -1; |