extern void pool_semaphore_create(int numSems);
extern void pool_semaphore_lock(int semNum);
+extern int pool_semaphore_lock_allow_interrupt(int semNum);
extern void pool_semaphore_unlock(int semNum);
extern BackendInfo *pool_get_node_info(int node_number);
*/
if (SERIALIZE_ACCEPT)
{
- pool_semaphore_lock(ACCEPT_FD_SEM);
+ if (pool_config->connection_life_time == 0)
+ {
+ pool_semaphore_lock(ACCEPT_FD_SEM);
+ }
+ else
+ {
+ int sts;
+
+ for (;;)
+ {
+ sts = pool_semaphore_lock_allow_interrupt(ACCEPT_FD_SEM);
+
+ /* Interrupted by alarm */
+ if (sts == -2)
+ {
+ /*
+ * Check if there are expired connection_life_time.
+ */
+ if (backend_timer_expired)
+ {
+ /*
+ * We add 10 seconds to connection_life_time so that there's
+ * enough margin.
+ */
+ int seconds = pool_config->connection_life_time + 10;
+
+ while (seconds-- > 0)
+ {
+ /* check backend timer is expired */
+ if (backend_timer_expired)
+ {
+ pool_backend_timer();
+ backend_timer_expired = 0;
+ break;
+ }
+ sleep(1);
+ }
+ }
+ }
+ else /* success or other error */
+ break;
+ }
+ }
+
set_ps_display("wait for connection request", false);
ereport(DEBUG1,
(errmsg("LOCKING select()")));
now = time(NULL);
ereport(DEBUG1,
- (errmsg("backend timer handler called at%ld", now)));
+ (errmsg("backend timer handler called at %ld", now)));
for (i=0;i<pool_config->max_pool;i++, p++)
{
(errmsg("failed to lock semaphore error:\"%s\"",strerror(errno))));
}
+/*
+ * Lock a semaphore (decrement count), blocking if count would be < 0.
+ * Unlike pool_semaphore_lock, this returns if interrupted.
+ * Return values:
+ * 0: succeeded in acquiring lock.
+ * -1: error.
+ * -2: interrupted.
+ */
+int
+pool_semaphore_lock_allow_interrupt(int semNum)
+{
+ int errStatus;
+ struct sembuf sops;
+
+ sops.sem_op = -1; /* decrement */
+ sops.sem_flg = SEM_UNDO;
+ sops.sem_num = semNum;
+
+ /*
+ * Note: if errStatus is -1 and errno == EINTR then it means we returned
+ * from the operation prematurely because we were sent a signal.
+ */
+ errStatus = semop(semId, &sops, 1);
+
+ if (errStatus < 0)
+ {
+ if (errno == EINTR)
+ {
+ ereport(DEBUG1,
+ (errmsg("interrupted while trying to lock semaphore")));
+ return -2;
+ }
+ else
+ {
+ ereport(WARNING,
+ (errmsg("failed to lock semaphore error:\"%s\"", strerror(errno))));
+ return -1;
+ }
+ }
+ return 0;
+}
+
/*
* Unlock a semaphore (increment count)
*/