summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-05-28 20:13:08 +0200
committerdimitri staessens <[email protected]>2016-05-28 20:22:54 +0200
commit6aea30b730381af91300397a02e684a462bf55a7 (patch)
tree1cc71310374a522ab3bf0141abd0f65e00eb7e39 /src
parentc2e21a6a8cdbc72dc7d6af5ecfe0ed42f4b18cf7 (diff)
downloadouroboros-6aea30b730381af91300397a02e684a462bf55a7.tar.gz
ouroboros-6aea30b730381af91300397a02e684a462bf55a7.zip
ipcpd: cleanup of IPC processes
This stops IPC processes from hanging due to bad locks. It first informs all threads that the IPCP is shutting down, then cancels all threads. Cancellation is still required because threads may be in accept() or receivefrom().
Diffstat (limited to 'src')
-rw-r--r--src/ipcpd/local/main.c12
-rw-r--r--src/ipcpd/shim-udp/main.c15
2 files changed, 18 insertions, 9 deletions
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index f3224de0..b07b0a52 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -246,20 +246,24 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGHUP:
case SIGQUIT:
if (info->si_pid == irmd_pid) {
+ bool clean_threads = false;
LOG_DBG("Terminating by order of %d. Bye.",
info->si_pid);
rw_lock_wrlock(&_ipcp->state_lock);
- if (_ipcp->state == IPCP_ENROLLED) {
- pthread_cancel(_ap_instance->sduloop);
- pthread_join(_ap_instance->sduloop, NULL);
- }
+ if (_ipcp->state == IPCP_ENROLLED)
+ clean_threads = true;
_ipcp->state = IPCP_SHUTDOWN;
rw_lock_unlock(&_ipcp->state_lock);
+ if (clean_threads) {
+ pthread_cancel(_ap_instance->sduloop);
+ pthread_join(_ap_instance->sduloop, NULL);
+ }
+
pthread_cancel(_ap_instance->mainloop);
}
default:
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 6869aaf0..c6c16ebf 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -834,13 +834,21 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- if (info->si_pid == irmd_pid || info->si_pid == 0) {
+ if (info->si_pid == irmd_pid) {
+ bool clean_threads = false;
LOG_DBG("Terminating by order of %d. Bye.",
info->si_pid);
rw_lock_wrlock(&_ipcp->state_lock);
- if (_ipcp->state == IPCP_ENROLLED) {
+ if (_ipcp->state == IPCP_ENROLLED)
+ clean_threads = true;
+
+ _ipcp->state = IPCP_SHUTDOWN;
+
+ rw_lock_unlock(&_ipcp->state_lock);
+
+ if (clean_threads) {
pthread_cancel(_ap_instance->handler);
pthread_cancel(_ap_instance->sdu_reader);
pthread_cancel(_ap_instance->sduloop);
@@ -852,9 +860,6 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
pthread_cancel(_ap_instance->mainloop);
- _ipcp->state = IPCP_SHUTDOWN;
-
- rw_lock_unlock(&_ipcp->state_lock);
}
default:
return;