summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiyuki Asaba2007-07-26 08:45:42 +0000
committerYoshiyuki Asaba2007-07-26 08:45:42 +0000
commit6bf711f0f62abfea0122bc03ae19356ba51ceff2 (patch)
tree3f2e0ecd5388922dfd274143429f2a339fd00baa
parent837db08586ce71178bcd5d1a905225dc6e0b6971 (diff)
SIGALRM handler didn't safe. Because it called non-reentrant functions.
We only set a flag in SIGALRM handler. Then we close expired connections in safe places.
-rw-r--r--child.c31
-rw-r--r--pool.h2
-rw-r--r--pool_connection_pool.c6
3 files changed, 37 insertions, 2 deletions
diff --git a/child.c b/child.c
index 3cc6398..3da7728 100644
--- a/child.c
+++ b/child.c
@@ -177,6 +177,13 @@ void do_child(int unix_fd, int inet_fd)
idle = 0;
child_idle_sec = 0;
+ /* check backend timer is expired */
+ if (backend_timer_expired)
+ {
+ pool_backend_timer();
+ backend_timer_expired = 0;
+ }
+
/* disable timeout */
pool_disable_timeout();
@@ -524,6 +531,7 @@ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *time
{
fd_set readmask;
int fds;
+ int save_errno;
SockAddr saddr;
int fd = 0;
@@ -565,6 +573,14 @@ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *time
fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, timeoutval);
+ save_errno = errno;
+ /* check backend timer is expired */
+ if (backend_timer_expired)
+ {
+ pool_backend_timer();
+ backend_timer_expired = 0;
+ }
+
/*
* following code fragment computes remaining timeout val in a
* portable way. Linux does this automazically but other platforms do not.
@@ -597,6 +613,8 @@ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *time
#endif
}
+ errno = save_errno;
+
if (fds == -1)
{
if (errno == EAGAIN || errno == EINTR)
@@ -634,13 +652,22 @@ static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *time
gettimeofday(&now1,0);
#endif
afd = accept(fd, (struct sockaddr *)&saddr.addr, &saddr.salen);
+
+ save_errno = errno;
+ /* check backend timer is expired */
+ if (backend_timer_expired)
+ {
+ pool_backend_timer();
+ backend_timer_expired = 0;
+ }
+ errno = save_errno;
if (afd < 0)
{
/*
* "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK)
- * can be silently ignored.
+ * can be silently ignored. And EINTR can be ignored
*/
- if (errno != EAGAIN && errno != EWOULDBLOCK)
+ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
pool_error("accept() failed. reason: %s", strerror(errno));
return NULL;
}
diff --git a/pool.h b/pool.h
index cf84131..d1e77d3 100644
--- a/pool.h
+++ b/pool.h
@@ -277,6 +277,7 @@ typedef struct {
*/
extern POOL_CONFIG pool_config; /* configuration values */
extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */
+extern volatile sig_atomic_t backend_timer_expired;
extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */
extern char remote_ps_data[]; /* used for set_ps_display */
@@ -312,6 +313,7 @@ extern int pool_init_cp(void);
extern POOL_CONNECTION_POOL *pool_create_cp(void);
extern POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket);
extern void pool_discard_cp(char *user, char *database, int protoMajor);
+extern void pool_backend_timer(void);
extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend,
POOL_CONNECTION_POOL *backend);
diff --git a/pool_connection_pool.c b/pool_connection_pool.c
index ceb801e..8195678 100644
--- a/pool_connection_pool.c
+++ b/pool_connection_pool.c
@@ -41,6 +41,7 @@
#include "pool.h"
POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */
+volatile sig_atomic_t backend_timer_expired = 0;
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);
@@ -258,6 +259,11 @@ void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend)
*/
RETSIGTYPE pool_backend_timer_handler(int sig)
{
+ backend_timer_expired = 1;
+}
+
+void pool_backend_timer(void)
+{
#define TMINTMAX 0x7fffffff
POOL_CONNECTION_POOL *p = pool_connection_pool;