summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYugo Nagata2016-06-15 06:24:21 +0000
committerYugo Nagata2017-07-03 05:35:59 +0000
commitd1be197d655d3a110eefdecaed631cb993288e3b (patch)
tree7467c95a73984ca6befe33fb28dc79007f05025d
parent41ab703896934450bc2c635ad90aed2c99861c2a (diff)
Fix a posible hang during health checkingV3_1_STABLE
Helath checking was hang when any data wasn't sent from backend after connect(2) succeeded. To fix this, pool_check_fd() returns 1 when select(2) exits with EINTR due to SIGALRM while health checkking is performed. Reported and patch provided by harukat and some modification by Yugo. Per bug #204. backported from 3.4 or later; https://git.postgresql.org/gitweb/?p=pgpool2.git;a=commitdiff;h=ed9f2900f1b611f5cfd52e8f758c3616861e60c0
-rw-r--r--main.c2
-rw-r--r--pool.h1
-rw-r--r--pool_process_query.c8
3 files changed, 10 insertions, 1 deletions
diff --git a/main.c b/main.c
index a32afaec2..f7de0ac2c 100644
--- a/main.c
+++ b/main.c
@@ -162,7 +162,7 @@ static int not_detach = 0; /* non 0 if non detach option (-n) is given */
static int stop_sig = SIGTERM; /* stopping signal default value */
-static volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */
+volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */
POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */
volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */
diff --git a/pool.h b/pool.h
index 8107b5c55..c3fb39bdb 100644
--- a/pool.h
+++ b/pool.h
@@ -397,6 +397,7 @@ extern bool run_as_pcp_child;
extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */
extern volatile sig_atomic_t backend_timer_expired; /* flag for connection closed timer is expired */
+extern volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */
extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */
extern int my_proc_id; /* process table id (!= UNIX's PID) */
extern POOL_SYSTEMDB_CONNECTION_POOL *system_db_info; /* systemdb */
diff --git a/pool_process_query.c b/pool_process_query.c
index fd815b998..27fbc4d55 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -1054,6 +1054,7 @@ int pool_check_fd(POOL_CONNECTION *cp)
int fds;
struct timeval timeout;
struct timeval *timeoutp;
+ int save_errno;
/*
* If SSL is enabled, we need to check SSL internal buffer
@@ -1083,8 +1084,15 @@ int pool_check_fd(POOL_CONNECTION *cp)
FD_SET(fd, &exceptmask);
fds = select(fd+1, &readmask, NULL, &exceptmask, timeoutp);
+ save_errno = errno;
if (fds == -1)
{
+ if (health_check_timer_expired && errno == EINTR)
+ {
+ pool_error("health check timed out while waiting for reading data");
+ errno = save_errno;
+ return 1;
+ }
if (errno == EAGAIN || errno == EINTR)
continue;