void na_connpool_assign_internal (na_env_t *env, na_connpool_t *connpool, int i, int *cur, int *fd, na_server_t *server) { if (connpool->active[i] == 0) { connpool->active[i] = 1; if (!na_server_connect(connpool->fd_pool[i], &server->addr)) { if (errno != EINPROGRESS && errno != EALREADY) { NA_DIE_WITH_ERROR(env, NA_ERROR_CONNECTION_FAILED); } } } connpool->mark[i] = 1; *fd = connpool->fd_pool[i]; *cur = i; }
void na_hc_callback (EV_P_ ev_timer *w, int revents) { int tsfd; int th_ret; na_env_t *env; th_ret = 0; env = (na_env_t *)w->data; if (SigExit == 1) { pthread_exit(&th_ret); return; } pthread_rwlock_rdlock(&LockReconf); pthread_mutex_lock(&env->lock_error_count); if (env->error_count_max > 0 && (env->error_count > env->error_count_max)) { na_hc_event_set(EV_A_ w, revents); env->error_count = 0; pthread_mutex_unlock(&env->lock_error_count); goto unlock_reconf; } pthread_mutex_unlock(&env->lock_error_count); tsfd = na_target_server_tcpsock_init(); if (tsfd <= 0) { na_hc_event_set(EV_A_ w, revents); na_error_count_up(env); NA_STDERR_MESSAGE(NA_ERROR_INVALID_FD); goto unlock_reconf; } na_target_server_hcsock_setup(tsfd); // health check if (!na_server_connect(tsfd, &env->target_server.addr)) { if (!env->is_refused_active) { if (errno != EINPROGRESS && errno != EALREADY) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = true; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch backup server"); } } } else { if (env->is_refused_active && na_hc_test_request(tsfd)) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = false; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch target server"); } else { if (!env->is_refused_active && !na_hc_test_request(tsfd)) { pthread_rwlock_wrlock(&env->lock_refused); env->is_refused_accept = true; env->is_refused_active = true; pthread_mutex_lock(&env->lock_connpool); na_connpool_switch(env); pthread_mutex_unlock(&env->lock_connpool); pthread_mutex_lock(&env->lock_current_conn); env->current_conn = 0; pthread_mutex_unlock(&env->lock_current_conn); env->is_refused_accept = false; pthread_rwlock_unlock(&env->lock_refused); NA_STDERR("switch backup server"); } } } close(tsfd); na_hc_event_set(EV_A_ w, revents); unlock_reconf: pthread_rwlock_unlock(&LockReconf); }