static gs_sigaction_func gs_signal_install_handler(void) { struct sigaction act, oact; /* * It is important to set SA_NODEFER flag, so this signal is not added * to the signal mask of the calling process on entry to the signal handler. */ sigemptyset(&act.sa_mask); act.sa_sigaction = gs_res_signal_handler; act.sa_flags = 0; act.sa_flags |= SA_SIGINFO; act.sa_flags |= SA_RESTART; if (sigaction(RES_SIGNAL, &act, &oact) < 0) { ereport(PANIC, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("not able to set up signal action handler"))); } /* Return previously installed handler */ return oact.sa_sigaction; } static void gs_res_signal_handler(int signo, siginfo_t* siginfo, void* context) { void* signature = NULL; MemoryContext oldContext = CurrentMemoryContext; /* * Calculate the timer signature and mark the SIGALRM by myself. This is * because SIGALRM is dilivered by current thread's timer. */ ThreadId thread_id = gs_thread_self(); signature = (void*)(SIGALRM + thread_id); if (siginfo->si_value.sival_ptr == signature) { if (SIG_IGN != t_thrd.signal_slot->gssignal->handlerList[SIGALRM] && SIG_DFL != t_thrd.signal_slot->gssignal->handlerList[SIGALRM]) { (t_thrd.signal_slot->gssignal->handlerList[SIGALRM])(SIGALRM); } CurrentMemoryContext = oldContext; return; } /* Hornour the signal */ gs_signal_handle(); CurrentMemoryContext = oldContext; return; }