Add checking socket state when connection pool is reused.
authorYoshiyuki Asaba <y-asaba at pgfoundry.org>
Tue, 6 Feb 2007 02:11:07 +0000 (02:11 +0000)
committerYoshiyuki Asaba <y-asaba at pgfoundry.org>
Tue, 6 Feb 2007 02:11:07 +0000 (02:11 +0000)
If socket is closed, pgpool try to create new connection pool.

pool_connection_pool.c

index d63a37ff3c3974e8ebb806ac42e6f18b8b667b63..3abac3a34e8bc93535b89e3a43be14d765667f6f 100644 (file)
@@ -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 secondary_backend);
 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.
@@ -95,6 +96,24 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor)
                        /* mark this connection is under use */
                        MASTER_CONNECTION(p)->closetime = 0;
                        POOL_SETMASK(&oldmask);
+
+                       if (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);
+
+                               if (DUAL_MODE)
+                               {
+                                       /* do not free memory! we did not allocate them */
+                                       pool_close(SECONDARY_CONNECTION(p)->con);
+                               }
+
+                               memset(p, 0, sizeof(POOL_CONNECTION_POOL));
+                               return NULL;
+                       }
+
                        return p;
                }
                p++;
@@ -462,3 +481,34 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p)
 
        return p;
 }
+
+/* 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;
+}