PostgreSQL数据库集簇初始化——initdb初始化数据库(设置中断信号处理函数)
设置中断信号处理函数,对终端命令行SIGHUP、程序中断SIGINT、程序退出SIGQUIT、软件中断SIGTERM和管道中断SIGPIPE等信号进行屏蔽,保证初始化工作顺利进行。
1 /* now we are starting to do real work, trap signals so we can clean up */ 2 /* some of these are not valid on Windows */ 3 #ifdef SIGHUP 4 pqsignal(SIGHUP, trapsig); 5 #endif 6 #ifdef SIGINT 7 pqsignal(SIGINT, trapsig); 8 #endif 9 #ifdef SIGQUIT 10 pqsignal(SIGQUIT, trapsig); 11 #endif 12 #ifdef SIGTERM 13 pqsignal(SIGTERM, trapsig); 14 #endif 15 /* Ignore SIGPIPE when writing to backend, so we can clean up */ 16 #ifdef SIGPIPE 17 pqsignal(SIGPIPE, SIG_IGN); 18 #endif
trapsig函数信号处理回调函数,Windows运行时文档(http://msdn.microsoft.com/library/en-us/vclib/html/_crt_signal.asp)禁止信号处理回调函数处理,包括IO、memory分配和系统调用。如果正在处理SIGPE,仅允许jmpbuf。I avoided doing the forbidden things by setting a flag instead of calling exit_nicely() directly. Windows下的SIGINT的行为:WIN32应用不支持SIGINT,包括Window 98/Me 和Windows NT/2000/XP。当按下CTRL+C时,Win32操作系统产生新的thread来处理中断。这会造成单thread比如UNIX,成为multithread,导致不正常的行为。 I have no idea how to handle this. (Strange they call UNIX an application!) So this will need some testing on Windows. 该回调函数调用后再次设置处理回调函数,设置caught_signal全局静态变量。
1 static void trapsig(int signum){ 2 /* handle systems that reset the handler, like Windows (grr) */ 3 pqsignal(signum, trapsig); 4 caught_signal = true; 5 }
pgsignal函数处于src/backend/libpq/pqsignal.c中,下面的代码用于处于针对不同的平台使用不同的信号设置函数。
1 #ifndef WIN32 2 /* Set up a signal handler */ 3 pqsigfunc pqsignal(int signo, pqsigfunc func) { 4 #if !defined(HAVE_POSIX_SIGNALS) 5 return signal(signo, func); 6 #else 7 struct sigaction act, oact; 8 act.sa_handler = func; 9 sigemptyset(&act.sa_mask); 10 act.sa_flags = 0; 11 if (signo != SIGALRM) 12 act.sa_flags |= SA_RESTART; 13 #ifdef SA_NOCLDSTOP 14 if (signo == SIGCHLD) 15 act.sa_flags |= SA_NOCLDSTOP; 16 #endif 17 if (sigaction(signo, &act, &oact) < 0) 18 return SIG_ERR; 19 return oact.sa_handler; 20 #endif /* !HAVE_POSIX_SIGNALS */ 21 } 22 #endif /* WIN32 */