diff options
| author | Yoshiyuki Asaba | 2007-07-26 08:45:42 +0000 |
|---|---|---|
| committer | Yoshiyuki Asaba | 2007-07-26 08:45:42 +0000 |
| commit | 6bf711f0f62abfea0122bc03ae19356ba51ceff2 (patch) | |
| tree | 3f2e0ecd5388922dfd274143429f2a339fd00baa | |
| parent | 837db08586ce71178bcd5d1a905225dc6e0b6971 (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.c | 31 | ||||
| -rw-r--r-- | pool.h | 2 | ||||
| -rw-r--r-- | pool_connection_pool.c | 6 |
3 files changed, 37 insertions, 2 deletions
@@ -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; } @@ -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; |
