#define Min(x, y) ((x) < (y) ? (x) : (y))
-#define MAX_NUM_SEMAPHORES 8
+#define MAX_NUM_SEMAPHORES 9
#define CONN_COUNTER_SEM 0
#define REQUEST_INFO_SEM 1
#define SHM_CACHE_SEM 2
#define ACCEPT_FD_SEM 5
#define SI_CRITICAL_REGION_SEM 6
#define FOLLOW_PRIMARY_SEM 7
+#define MAIN_EXIT_HANDLER_SEM 8 /* used in exit_hander in pgpool main process */
#define MAX_REQUEST_QUEUE_SIZE 10
#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION 10 /* time in seconds to keep
extern char *conf_file;
extern char *hba_file;
-static int exiting = 0; /* non 0 if I'm exiting */
-static int switching = 0; /* non 0 if I'm failing over or degenerating */
+static volatile sig_atomic_t exiting = 0; /* non 0 if I'm exiting */
+static volatile sig_atomic_t switching = 0; /* non 0 if I'm failing over or degenerating */
POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */
volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */
}
+/*
+ * Pgpool main process exit handler
+ */
static RETSIGTYPE exit_handler(int sig)
{
int *walk;
errno = save_errno;
return;
}
- exiting = 1;
- processState = EXITING;
+ /*
+ * Check if another exit handler instance is already running. It is
+ * possible that exit_handler is interrupted in the middle by other
+ * signal.
+ */
+ if (exiting)
+ {
+ ereport(LOG,
+ (errmsg("exit handler (signal: %d) called. but exit handler is already in progress", sig)));
+ POOL_SETMASK(&UnBlockSig);
+ errno = save_errno;
+ return;
+ }
+
+ /* Check to make sure that other exit handler is not running */
+ pool_semaphore_lock(MAIN_EXIT_HANDLER_SEM);
+ if (exiting == 0)
+ {
+ exiting = 1;
+ pool_semaphore_unlock(MAIN_EXIT_HANDLER_SEM);
+ }
+ else
+ {
+ pool_semaphore_unlock(MAIN_EXIT_HANDLER_SEM);
+ ereport(LOG,
+ (errmsg("exit handler (signal: %d) called. but exit handler is already in progress", sig)));
+ POOL_SETMASK(&UnBlockSig);
+ errno = save_errno;
+ return;
+ }
+
+ processState = EXITING;
ereport(LOG,
- (errmsg("shutting down")));
+ (errmsg("shutting down by signal %d", sig)));
+
/* Close listen socket if they are already initialized */
if (fds)
{