diff options
author | Sander Vrijders <[email protected]> | 2016-08-11 17:39:39 +0200 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2016-08-11 17:39:39 +0200 |
commit | 5432e665fd6eac776c5985d98058e5c4645ec0e4 (patch) | |
tree | 10b398bf23356751a961c332a9dff053c6927f24 /src/ipcpd/normal/main.c | |
parent | cf30e07cf862b117013e8c7fa2fb5c2ac8fef245 (diff) | |
download | ouroboros-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.c | 59 |
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."); |