/* * send frontend exiting messages to all connections. this is called * in any case when child process exits, for example failover, child * life time expires or child max connections expires. */ static void send_frontend_exits(void) { int i; POOL_CONNECTION_POOL *p = pool_connection_pool; #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif POOL_SETMASK2(&BlockSig, &oldmask); for (i=0;i<pool_config->max_pool;i++, p++) { if (!MASTER_CONNECTION(p)) continue; if (!MASTER_CONNECTION(p)->sp) continue; if (MASTER_CONNECTION(p)->sp->user == NULL) continue; pool_send_frontend_exits(p); } POOL_SETMASK(&oldmask); }
/* * find connection by user and database */ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket) { #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif int i; POOL_CONNECTION_POOL *p = pool_connection_pool; if (p == NULL) { pool_error("pool_get_cp: pool_connection_pool is not initialized"); return NULL; } POOL_SETMASK2(&BlockSig, &oldmask); for (i=0;i<pool_config.max_pool;i++) { if (MASTER_CONNECTION(p) && MASTER_CONNECTION(p)->sp->major == protoMajor && MASTER_CONNECTION(p)->sp->user != NULL && strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 && strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0) { /* mark this connection is under use */ MASTER_CONNECTION(p)->closetime = 0; POOL_SETMASK(&oldmask); if (check_socket && (check_socket_status(MASTER(p)->fd) < 0 || (DUAL_MODE && check_socket_status(MASTER(p)->fd) < 0))) { pool_log("connection closed. retry to create new connection pool."); pool_free_startup_packet(MASTER_CONNECTION(p)->sp); pool_close(MASTER_CONNECTION(p)->con); free(MASTER_CONNECTION(p)); if (DUAL_MODE) { pool_close(SECONDARY_CONNECTION(p)->con); free(SECONDARY_CONNECTION(p)); } memset(p, 0, sizeof(POOL_CONNECTION_POOL)); return NULL; } return p; } p++; } POOL_SETMASK(&oldmask); return NULL; }
void pool_debug(const char *fmt,...) { va_list ap; #ifdef HAVE_ASPRINTF char *fmt2; int len; #endif #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif if (run_as_pcp_child) { if (!debug) return; } else { if (pool_config->debug_level <= 0) return; } POOL_SETMASK2(&BlockSig, &oldmask); /* Write message to syslog */ if (pool_config->logsyslog == 1) { va_start(ap, fmt); vsyslog(pool_config->syslog_facility | LOG_DEBUG, fmt, ap); va_end(ap); POOL_SETMASK(&oldmask); return; } #ifdef HAVE_ASPRINTF len = asprintf(&fmt2, "%s %s\n", optstring(1), fmt); if (len >= 0 && fmt2) { va_start(ap, fmt); vfprintf(stderr, fmt2, ap); va_end(ap); fflush(stderr); free(fmt2); } #else fprintf(stderr, "%s %s", optstring(1)); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); #endif POOL_SETMASK(&oldmask); }
/* * Count up connection counter (from frontend to pgpool) * in shared memory */ static void connection_count_up(void) { #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif POOL_SETMASK2(&BlockSig, &oldmask); pool_semaphore_lock(CONN_COUNTER_SEM); Req_info->conn_counter++; pool_semaphore_unlock(CONN_COUNTER_SEM); POOL_SETMASK(&oldmask); }
void pool_error(const char *fmt,...) { va_list ap; #ifdef HAVE_ASPRINTF char *fmt2; int len; #endif #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif POOL_SETMASK2(&BlockSig, &oldmask); /* Write error message to syslog */ if (pool_config->logsyslog == 1) { va_start(ap, fmt); vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap); va_end(ap); POOL_SETMASK(&oldmask); return; } if (pool_config->print_timestamp) #ifdef HAVE_ASPRINTF len = asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int)getpid(), fmt); else len = asprintf(&fmt2, "ERROR: pid %d: %s\n", (int)getpid(), fmt); if (len >= 0 && fmt2) { va_start(ap, fmt); vfprintf(stderr, fmt2, ap); va_end(ap); fflush(stderr); free(fmt2); } #else fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int)getpid()); else
/* * Count down connection counter (from frontend to pgpool) * in shared memory */ static void connection_count_down(void) { #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif POOL_SETMASK2(&BlockSig, &oldmask); pool_semaphore_lock(CONN_COUNTER_SEM); /* * Make sure that we do not decrement too much. If failed to read * a start up packet, or receive cancel request etc., * connection_count_down() is called and goes back to the * connection accept loop. Problem is, at the very beginning of * the connection accept loop, if we have received a signal, we * call child_exit() which calls connection_count_down() again. */ if (Req_info->conn_counter > 0) Req_info->conn_counter--; pool_semaphore_unlock(CONN_COUNTER_SEM); POOL_SETMASK(&oldmask); }
/* * find connection by user and database */ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket) { #ifdef HAVE_SIGPROCMASK sigset_t oldmask; #else int oldmask; #endif int i, freed = 0; ConnectionInfo *info; POOL_CONNECTION_POOL *p = pool_connection_pool; if (p == NULL) { pool_error("pool_get_cp: pool_connection_pool is not initialized"); return NULL; } POOL_SETMASK2(&BlockSig, &oldmask); for (i=0;i<pool_config->max_pool;i++) { if (MASTER_CONNECTION(p) && MASTER_CONNECTION(p)->sp && MASTER_CONNECTION(p)->sp->major == protoMajor && MASTER_CONNECTION(p)->sp->user != NULL && strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 && strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0) { int sock_broken = 0; int j; /* mark this connection is under use */ MASTER_CONNECTION(p)->closetime = 0; for (j=0;j<NUM_BACKENDS;j++) { p->info[j].counter++; } POOL_SETMASK(&oldmask); if (check_socket) { for (j=0;j<NUM_BACKENDS;j++) { if (!VALID_BACKEND(j)) continue; if (CONNECTION_SLOT(p, j)) { sock_broken = check_socket_status(CONNECTION(p, j)->fd); if (sock_broken < 0) break; } else { sock_broken = -1; break; } } if (sock_broken < 0) { pool_log("connection closed. retry to create new connection pool."); for (j=0;j<NUM_BACKENDS;j++) { if (!VALID_BACKEND(j) || (CONNECTION_SLOT(p, j) == NULL)) continue; if (!freed) { pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp); freed = 1; } pool_close(CONNECTION(p, j)); free(CONNECTION_SLOT(p, j)); } info = p->info; memset(p, 0, sizeof(POOL_CONNECTION_POOL_SLOT)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); POOL_SETMASK(&oldmask); return NULL; } } POOL_SETMASK(&oldmask); pool_index = i; return p; } p++; } POOL_SETMASK(&oldmask); return NULL; }