void* netconf_rpc_thread(void* UNUSED(arg)) { struct client_struct* client; do { /* GLOBAL READ LOCK */ pthread_rwlock_rdlock(&netopeer_state.global_lock); for (client = netopeer_state.clients; client != NULL; client = client->next) { if (client->to_free) { continue; } switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: np_ssh_client_netconf_rpc((struct client_struct_ssh*)client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: np_tls_client_netconf_rpc((struct client_struct_tls*)client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } } /* GLOBAL READ UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); usleep(netopeer_options.response_time*1000); } while (!quit); #ifdef NP_TLS np_tls_thread_cleanup(); #endif return NULL; }
void* client_main_thread(void* arg) { struct client_struct* client = (struct client_struct*)arg; int skip_sleep; do { skip_sleep = 0; /* GLOBAL READ LOCK */ pthread_rwlock_rdlock(&netopeer_state.global_lock); switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: skip_sleep += np_ssh_client_transport((struct client_struct_ssh*)client); skip_sleep += np_ssh_client_netconf_rpc((struct client_struct_ssh*)client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: skip_sleep += np_tls_client_transport((struct client_struct_tls*)client); skip_sleep += np_tls_client_netconf_rpc((struct client_struct_tls*)client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } /* GLOBAL READ UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); if (!skip_sleep) { /* we did not do anything productive, so let the thread sleep */ usleep(netopeer_options.response_time*1000); } } while (!client->to_free); /* GLOBAL WRITE LOCK */ pthread_rwlock_wrlock(&netopeer_state.global_lock); np_client_detach(&netopeer_state.clients, client); /* GLOBAL WRITE UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); switch (client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: client_free_ssh((struct client_struct_ssh*)client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: client_free_tls((struct client_struct_tls*)client); break; #endif default: free(client); break; } #ifdef NP_TLS np_tls_thread_cleanup(); #endif pthread_detach(pthread_self()); return NULL; }