summaryrefslogtreecommitdiff
path: root/src/ipcpd/ipcp.c
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@intec.ugent.be>2017-01-04 15:25:15 +0100
committerdimitri staessens <dimitri.staessens@intec.ugent.be>2017-01-04 15:59:41 +0100
commit4384cd203a958373cf0ab959afb688f9eeba05fc (patch)
tree8190cda7271de35bae0725240e29ea33fce1ddc3 /src/ipcpd/ipcp.c
parentbbabc773eccf7fe414428b3c8e4a7d3521ca7582 (diff)
downloadouroboros-4384cd203a958373cf0ab959afb688f9eeba05fc.tar.gz
ouroboros-4384cd203a958373cf0ab959afb688f9eeba05fc.zip
ipcpd: Add boot and shutdown operations
These operations separe the starting and joining of the main ipcp threads into ipcp_boot() and ipcp_shutdown() operations. This allows the proper cleanup of user data and user threads after the IPCP is requested to shut down.
Diffstat (limited to 'src/ipcpd/ipcp.c')
-rw-r--r--src/ipcpd/ipcp.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index c47f1181..e44fafe2 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -279,13 +279,12 @@ static void * ipcp_main_loop(void * o)
int ipcp_init(enum ipcp_type type, struct ipcp_ops * ops)
{
pthread_condattr_t cattr;
- int t;
struct timeval tv = {(IPCP_ACCEPT_TIMEOUT / 1000),
(IPCP_ACCEPT_TIMEOUT % 1000) * 1000};
ipcpi.irmd_fd = -1;
- ipcpi.state = IPCP_INIT;
+ ipcpi.state = IPCP_NULL;
ipcpi.threadpool = malloc(sizeof(pthread_t) * IPCPD_THREADPOOL_SIZE);
if (ipcpi.threadpool == NULL) {
@@ -329,20 +328,40 @@ int ipcp_init(enum ipcp_type type, struct ipcp_ops * ops)
#endif
pthread_cond_init(&ipcpi.state_cond, &cattr);
- for (t = 0; t < IPCPD_THREADPOOL_SIZE; ++t)
- pthread_create(&ipcpi.threadpool[t], NULL,
- ipcp_main_loop, NULL);
-
return 0;
}
-void ipcp_fini()
+int ipcp_boot()
{
int t;
+ for (t = 0; t < IPCPD_THREADPOOL_SIZE; ++t) {
+ if (pthread_create(&ipcpi.threadpool[t], NULL,
+ ipcp_main_loop, NULL)) {
+ int i;
+ LOG_ERR("Failed to create main thread.");
+ ipcp_set_state(IPCP_NULL);
+ for (i = 0; i < t; ++i)
+ pthread_join(ipcpi.threadpool[i], NULL);
+ return -1;
+ }
+ }
+
+ ipcpi.state = IPCP_INIT;
+ return 0;
+}
+
+void ipcp_shutdown()
+{
+ int t;
for (t = 0; t < IPCPD_THREADPOOL_SIZE; ++t)
pthread_join(ipcpi.threadpool[t], NULL);
+ LOG_DBG("IPCP %d shutting down. Bye.", getpid());
+}
+
+void ipcp_fini()
+{
close(ipcpi.sockfd);
if (unlink(ipcpi.sock_path))
LOG_DBG("Could not unlink %s.", ipcpi.sock_path);
@@ -353,6 +372,7 @@ void ipcp_fini()
ipcp_data_destroy(ipcpi.data);
pthread_cond_destroy(&ipcpi.state_cond);
+ pthread_mutex_destroy(&ipcpi.state_mtx);
pthread_rwlock_destroy(&ipcpi.state_lock);
}