/* * Do house keeping works when pgpool child process exits */ void child_exit(int code) { if (getpid() == mypid) { pool_log("child_exit: called from pgpool main. ignored."); return; } /* count down global connection counter */ if (accepted) connection_count_down(); /* prepare to shutdown connections to system db */ if(pool_config->parallel_mode || pool_config->enable_query_cache) { if (system_db_info->pgconn) pool_close_libpq_connection(); if (pool_system_db_connection()) pool_close(pool_system_db_connection()->con); } if (pool_config->memory_cache_enabled && !pool_is_shmem_cache()) { memcached_disconnect(); } /* let backend know now we are exiting */ if (pool_connection_pool) send_frontend_exits(); exit(code); }
void pool_backend_timer(void) { #define TMINTMAX 0x7fffffff POOL_CONNECTION_POOL *p = pool_connection_pool; int i, j; time_t now; time_t nearest = TMINTMAX; ConnectionInfo *info; POOL_SETMASK(&BlockSig); now = time(NULL); pool_debug("pool_backend_timer_handler called at %ld", now); 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; /* timer expire? */ if (MASTER_CONNECTION(p)->closetime) { int freed = 0; pool_debug("pool_backend_timer_handler: expire time: %ld", MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time); if (now >= (MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time)) { /* discard expired connection */ pool_debug("pool_backend_timer_handler: expires user %s database %s", MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database); pool_send_frontend_exits(p); for (j=0;j<NUM_BACKENDS;j++) { if (!VALID_BACKEND(j)) 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)); p->info = info; memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); /* prepare to shutdown connections to system db */ if(pool_config->system_db_dynamic_connection && (pool_config->parallel_mode || pool_config->enable_query_cache)) { if (system_db_info->pgconn) pool_close_libpq_connection(); if (pool_system_db_connection() && pool_system_db_connection()->con) { pool_send_frontend_exit(pool_system_db_connection()->con); pool_close(pool_system_db_connection()->con); } if( system_db_info->connection ) { free( system_db_info->connection ); memset(system_db_info->connection, 0, sizeof(POOL_CONNECTION_POOL_SLOT)); system_db_info->connection = NULL; } } } else { /* look for nearest timer */ if (MASTER_CONNECTION(p)->closetime < nearest) nearest = MASTER_CONNECTION(p)->closetime; } } } /* any remaining timer */ if (nearest != TMINTMAX) { nearest = pool_config->connection_life_time - (now - nearest); if (nearest <= 0) nearest = 1; pool_signal(SIGALRM, pool_backend_timer_handler); alarm(nearest); } POOL_SETMASK(&UnBlockSig); }