summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/main.c
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2016-08-11 17:39:39 +0200
committerSander Vrijders <[email protected]>2016-08-11 17:39:39 +0200
commit5432e665fd6eac776c5985d98058e5c4645ec0e4 (patch)
tree10b398bf23356751a961c332a9dff053c6927f24 /src/ipcpd/normal/main.c
parentcf30e07cf862b117013e8c7fa2fb5c2ac8fef245 (diff)
downloadouroboros-5432e665fd6eac776c5985d98058e5c4645ec0e4.tar.gz
ouroboros-5432e665fd6eac776c5985d98058e5c4645ec0e4.zip
ipcpd: Add condition variable to IPCP state
This adds a condition variable to the IPCP state, so that upon state changes any listeners to state changes can be notified. It also replaces the read/write lock with a mutex in order to be able to do so.
Diffstat (limited to 'src/ipcpd/normal/main.c')
-rw-r--r--src/ipcpd/normal/main.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index b5aad271..ea8d75e1 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -73,11 +73,11 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
LOG_DBG("Terminating by order of %d. Bye.",
info->si_pid);
- pthread_rwlock_wrlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
- _ipcp->state = IPCP_SHUTDOWN;
+ ipcp_state_change(_ipcp, IPCP_SHUTDOWN);
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
pthread_cancel(normal_data(_ipcp)->mainloop);
@@ -97,21 +97,21 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c)
static int normal_ipcp_name_reg(char * name)
{
- pthread_rwlock_rdlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
if (_ipcp->state != IPCP_ENROLLED) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_DBGF("Won't register with non-enrolled IPCP.");
return -1; /* -ENOTENROLLED */
}
if (ipcp_data_add_reg_entry(_ipcp->data, name)) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_ERR("Failed to add %s to local registry.", name);
return -1;
}
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_DBG("Registered %s.", name);
@@ -120,59 +120,56 @@ static int normal_ipcp_name_reg(char * name)
static int normal_ipcp_name_unreg(char * name)
{
- pthread_rwlock_rdlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
ipcp_data_del_reg_entry(_ipcp->data, name);
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
return 0;
}
static int normal_ipcp_enroll(char * dif_name)
{
- pthread_rwlock_rdlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
if (_ipcp->state != IPCP_INIT) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_ERR("Won't enroll an IPCP that is not in INIT.");
return -1; /* -ENOTINIT */
}
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
if (fmgr_mgmt_flow(dif_name)) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_ERR("Failed to establish management flow.");
return -1;
}
- /* FIXME: Wait passively until state changed to ENROLLED */
- pthread_rwlock_rdlock(&_ipcp->state_lock);
- while (_ipcp->state != IPCP_ENROLLED) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
- sched_yield();
- pthread_rwlock_rdlock(&_ipcp->state_lock);
- }
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ /* FIXME: Change into timedwait, see solution in irmd first */
+ pthread_mutex_lock(&_ipcp->state_lock);
+ while (_ipcp->state != IPCP_ENROLLED)
+ pthread_cond_wait(&_ipcp->state_cond, &_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
return 0;
}
static int normal_ipcp_bootstrap(struct dif_config * conf)
{
- LOG_DBGF("bootstrapping in dif %s.", conf->dif_name);
+ LOG_DBGF("Bootstrapping in DIF %s.", conf->dif_name);
- pthread_rwlock_rdlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
if (_ipcp->state != IPCP_INIT) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_ERR("Won't bootstrap an IPCP that is not in INIT.");
return -1; /* -ENOTINIT */
}
if (ribmgr_bootstrap(conf)) {
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
LOG_ERR("Failed to bootstrap RIB manager.");
return -1;
}
@@ -182,9 +179,9 @@ static int normal_ipcp_bootstrap(struct dif_config * conf)
return -1;
}
- _ipcp->state = IPCP_ENROLLED;
+ ipcp_state_change(_ipcp, IPCP_ENROLLED);
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
return 0;
}
@@ -239,7 +236,7 @@ void normal_ipcp_data_destroy()
if (_ipcp == NULL)
return;
- pthread_rwlock_wrlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
if (_ipcp->state != IPCP_SHUTDOWN)
LOG_WARN("Cleaning up while not in shutdown.");
@@ -249,7 +246,7 @@ void normal_ipcp_data_destroy()
if (normal_data(_ipcp)->rb != NULL)
shm_ap_rbuff_close(normal_data(_ipcp)->rb);
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
free(_ipcp->data);
}
@@ -323,7 +320,7 @@ int main(int argc, char * argv[])
exit(EXIT_FAILURE);
}
- pthread_rwlock_wrlock(&_ipcp->state_lock);
+ pthread_mutex_lock(&_ipcp->state_lock);
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
@@ -332,7 +329,7 @@ int main(int argc, char * argv[])
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
- pthread_rwlock_unlock(&_ipcp->state_lock);
+ pthread_mutex_unlock(&_ipcp->state_lock);
if (ipcp_create_r(getpid())) {
LOG_ERR("Failed to notify IRMd we are initialized.");