pgpool2.git / summary / log / commit / refs

commit    a9fb83ff63c14f6c173a2c38eb439d8900510d23
Author:   Yoshiyuki Asaba <y-asaba at pgfoundry.org>
Date:     Tue Feb 06 02:46:58 2007 +0000

    Add checking socket state when connection pool is reused.
    If socket is closed, pgpool try to create new connection pool.


pool_connection_pool.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/pool_connection_pool.c b/pool_connection_pool.c index 56b43e7c7..44d1eb38a 100644 --- a/pool_connection_pool.c +++ b/pool_connection_pool.c @@ -44,6 +44,7 @@ POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot); static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p); +static int check_socket_status(int fd); /* * initialize connection pools. this should be called once at the startup. @@ -79,7 +80,8 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor) int oldmask; #endif - int i; + int i, j, freed = 0; + ConnectionInfo *info; POOL_CONNECTION_POOL *p = pool_connection_pool; @@ -99,10 +101,45 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor) strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 && strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0) { + int sock_broken = 0; + /* mark this connection is under use */ MASTER_CONNECTION(p)->closetime = 0; p->info->counter++; POOL_SETMASK(&oldmask); + + for (j=0;j<NUM_BACKENDS;j++) + { + if (!VALID_BACKEND(j)) + continue; + + sock_broken = check_socket_status(CONNECTION(p, j)->fd); + if (sock_broken < 0) + 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)) + continue; + + if (!freed) + { + pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp); + freed = 1; + } + + pool_close(CONNECTION(p, j)); + } + info = p->info; + memset(p, 0, sizeof(POOL_CONNECTION_POOL)); + p->info = info; + memset(p->info, 0, sizeof(ConnectionInfo)); + return NULL; + } return p; } p++; @@ -530,3 +567,34 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) return NULL; } + +/* check_socket_status() + * RETURN: 0 => OK + * -1 => broken socket. + */ +static int check_socket_status(int fd) +{ + fd_set rfds; + int result; + struct timeval t; + + for (;;) + { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + t.tv_sec = t.tv_usec = 0; + + result = select(fd+1, &rfds, NULL, NULL, &t); + if (result < 0 && errno == EINTR) + { + continue; + } + else + { + return (result == 0 ? 0 : -1); + } + } + + return -1; +} [parent: 57d14e7dfe3a]