diff -cr postgresql-snapshot-030203/src/backend/commands/async.c postgresql-win32-mha/src/backend/commands/async.c *** postgresql-snapshot-030203/src/backend/commands/async.c Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/backend/commands/async.c Wed Feb 4 00:29:27 2004 *************** *** 83,89 **** #include "commands/async.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" - #include "libpq/pqsignal.h" #include "miscadmin.h" #include "storage/ipc.h" #include "tcop/tcopprot.h" --- 83,88 ---- *************** *** 498,504 **** * for some reason. It's OK to send the signal first, because * the other guy can't read pg_listener until we unlock it. */ ! if (pqkill(listenerPID, SIGUSR2) < 0) { /* * Get rid of pg_listener entry if it refers to a PID that --- 497,503 ---- * for some reason. It's OK to send the signal first, because * the other guy can't read pg_listener until we unlock it. */ ! if (kill(listenerPID, SIGUSR2) < 0) { /* * Get rid of pg_listener entry if it refers to a PID that diff -cr postgresql-snapshot-030203/src/backend/libpq/pqsignal.c postgresql-win32-mha/src/backend/libpq/pqsignal.c *** postgresql-snapshot-030203/src/backend/libpq/pqsignal.c Tue Jan 27 01:46:58 2004 --- postgresql-win32-mha/src/backend/libpq/pqsignal.c Wed Feb 4 21:57:14 2004 *************** *** 39,55 **** * at all. * ------------------------------------------------------------------------*/ #ifdef WIN32 - #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x0400 #endif #include "postgres.h" - #ifndef WIN32 #include - #else - #include - #endif #include "libpq/pqsignal.h" --- 39,50 ---- *************** *** 180,185 **** --- 175,181 ---- /* Signal handling thread function */ static DWORD WINAPI pg_signal_thread(LPVOID param); + static BOOL WINAPI pg_console_handler(DWORD dwCtrlType); /* Initialization */ void *************** *** 214,219 **** --- 210,220 ---- fprintf(stderr, gettext("Failed to create signal handler thread!\n")); exit(1); } + + if (!SetConsoleCtrlHandler(pg_console_handler, TRUE)) { + fprintf(stderr, gettext("Failed to set console control handler!\n")); + /* Non-fatal, continue executing */ + } } *************** *** 344,350 **** */ ! static void pg_queue_signal(int signum) { if (signum >= PG_SIGNAL_COUNT || signum < 0) --- 345,351 ---- */ ! void pg_queue_signal(int signum) { if (signum >= PG_SIGNAL_COUNT || signum < 0) *************** *** 427,432 **** --- 428,448 ---- CloseHandle(pipe); } return 0; + } + + + /* Console control handler will execute on a thread created + by the OS at the time of invokation */ + static BOOL WINAPI pg_console_handler(DWORD dwCtrlType) { + printf("Console handler being called!\n");fflush(stdout); + if (dwCtrlType == CTRL_C_EVENT || + dwCtrlType == CTRL_BREAK_EVENT || + dwCtrlType == CTRL_CLOSE_EVENT || + dwCtrlType == CTRL_SHUTDOWN_EVENT) { + pg_queue_signal(SIGINT); + return TRUE; + } + return FALSE; } diff -cr postgresql-snapshot-030203/src/backend/port/sysv_sema.c postgresql-win32-mha/src/backend/port/sysv_sema.c *** postgresql-snapshot-030203/src/backend/port/sysv_sema.c Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/backend/port/sysv_sema.c Wed Feb 4 00:29:27 2004 *************** *** 31,37 **** #include "miscadmin.h" #include "storage/ipc.h" #include "storage/pg_sema.h" - #include "libpq/pqsignal.h" #ifndef HAVE_UNION_SEMUN --- 31,36 ---- *************** *** 233,239 **** continue; /* oops, GETPID failed */ if (creatorPID != getpid()) { ! if (pqkill(creatorPID, 0) == 0 || errno != ESRCH) continue; /* sema belongs to a live process */ } --- 232,238 ---- continue; /* oops, GETPID failed */ if (creatorPID != getpid()) { ! if (kill(creatorPID, 0) == 0 || errno != ESRCH) continue; /* sema belongs to a live process */ } diff -cr postgresql-snapshot-030203/src/backend/port/sysv_shmem.c postgresql-win32-mha/src/backend/port/sysv_shmem.c *** postgresql-snapshot-030203/src/backend/port/sysv_shmem.c Mon Feb 2 01:11:31 2004 --- postgresql-win32-mha/src/backend/port/sysv_shmem.c Wed Feb 4 00:29:27 2004 *************** *** 33,39 **** #include "miscadmin.h" #include "storage/ipc.h" #include "storage/pg_shmem.h" - #include "libpq/pqsignal.h" typedef key_t IpcMemoryKey; /* shared memory key passed to shmget(2) */ --- 33,38 ---- *************** *** 304,310 **** hdr = (PGShmemHeader *) memAddress; if (hdr->creatorPID != getpid()) { ! if (pqkill(hdr->creatorPID, 0) == 0 || errno != ESRCH) { shmdt(memAddress); continue; /* segment belongs to a live process */ --- 303,309 ---- hdr = (PGShmemHeader *) memAddress; if (hdr->creatorPID != getpid()) { ! if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH) { shmdt(memAddress); continue; /* segment belongs to a live process */ diff -cr postgresql-snapshot-030203/src/backend/postmaster/postmaster.c postgresql-win32-mha/src/backend/postmaster/postmaster.c *** postgresql-snapshot-030203/src/backend/postmaster/postmaster.c Wed Jan 28 22:02:40 2004 --- postgresql-win32-mha/src/backend/postmaster/postmaster.c Wed Feb 4 21:45:58 2004 *************** *** 308,313 **** --- 308,314 ---- static void win32_AddChild(pid_t pid, HANDLE handle); static void win32_RemoveChild(pid_t pid); static pid_t win32_waitpid(int *exitstatus); + static DWORD WINAPI win32_sigchld_waiter(LPVOID param); static pid_t *win32_childPIDArray; static HANDLE *win32_childHNDArray; *************** *** 850,856 **** /* FIXME: [fork/exec] Ideally, we would resize these arrays with changes * in MaxBackends, but this'll do as a first order solution. */ ! win32_childPIDArray = (HANDLE*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(pid_t)); win32_childHNDArray = (HANDLE*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(HANDLE)); if (!win32_childPIDArray || !win32_childHNDArray) ereport(LOG, --- 851,857 ---- /* FIXME: [fork/exec] Ideally, we would resize these arrays with changes * in MaxBackends, but this'll do as a first order solution. */ ! win32_childPIDArray = (pid_t*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(pid_t)); win32_childHNDArray = (HANDLE*)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(HANDLE)); if (!win32_childPIDArray || !win32_childHNDArray) ereport(LOG, *************** *** 1566,1572 **** ereport(DEBUG2, (errmsg_internal("processing cancel request: sending SIGINT to process %d", backendPID))); ! pqkill(bp->pid, SIGINT); } else /* Right PID, wrong key: no way, Jose */ --- 1567,1573 ---- ereport(DEBUG2, (errmsg_internal("processing cancel request: sending SIGINT to process %d", backendPID))); ! kill(bp->pid, SIGINT); } else /* Right PID, wrong key: no way, Jose */ *************** *** 1738,1744 **** * will start a new one with a possibly changed config */ if (BgWriterPID != 0) ! pqkill(BgWriterPID, SIGTERM); } PG_SETMASK(&UnBlockSig); --- 1739,1745 ---- * will start a new one with a possibly changed config */ if (BgWriterPID != 0) ! kill(BgWriterPID, SIGTERM); } PG_SETMASK(&UnBlockSig); *************** *** 1772,1778 **** * Wait for children to end their work and ShutdownDataBase. */ if (BgWriterPID != 0) ! pqkill(BgWriterPID, SIGTERM); if (Shutdown >= SmartShutdown) break; Shutdown = SmartShutdown; --- 1773,1779 ---- * Wait for children to end their work and ShutdownDataBase. */ if (BgWriterPID != 0) ! kill(BgWriterPID, SIGTERM); if (Shutdown >= SmartShutdown) break; Shutdown = SmartShutdown; *************** *** 1806,1812 **** * and exit) and ShutdownDataBase when they are gone. */ if (BgWriterPID != 0) ! pqkill(BgWriterPID, SIGTERM); if (Shutdown >= FastShutdown) break; ereport(LOG, --- 1807,1813 ---- * and exit) and ShutdownDataBase when they are gone. */ if (BgWriterPID != 0) ! kill(BgWriterPID, SIGTERM); if (Shutdown >= FastShutdown) break; ereport(LOG, *************** *** 1854,1866 **** * properly shutdown data base system. */ if (BgWriterPID != 0) ! pqkill(BgWriterPID, SIGQUIT); ereport(LOG, (errmsg("received immediate shutdown request"))); if (ShutdownPID > 0) ! pqkill(ShutdownPID, SIGQUIT); if (StartupPID > 0) ! pqkill(StartupPID, SIGQUIT); if (DLGetHead(BackendList)) SignalChildren(SIGQUIT); ExitPostmaster(0); --- 1855,1867 ---- * properly shutdown data base system. */ if (BgWriterPID != 0) ! kill(BgWriterPID, SIGQUIT); ereport(LOG, (errmsg("received immediate shutdown request"))); if (ShutdownPID > 0) ! kill(ShutdownPID, SIGQUIT); if (StartupPID > 0) ! kill(StartupPID, SIGQUIT); if (DLGetHead(BackendList)) SignalChildren(SIGQUIT); ExitPostmaster(0); *************** *** 2130,2136 **** (errmsg_internal("sending %s to process %d", (SendStop ? "SIGSTOP" : "SIGQUIT"), (int) bp->pid))); ! pqkill(bp->pid, (SendStop ? SIGSTOP : SIGQUIT)); } } else --- 2131,2137 ---- (errmsg_internal("sending %s to process %d", (SendStop ? "SIGSTOP" : "SIGQUIT"), (int) bp->pid))); ! kill(bp->pid, (SendStop ? SIGSTOP : SIGQUIT)); } } else *************** *** 2225,2231 **** (errmsg_internal("sending signal %d to process %d", signal, (int) bp->pid))); ! pqkill(bp->pid, signal); } curr = next; --- 2226,2232 ---- (errmsg_internal("sending signal %d to process %d", signal, (int) bp->pid))); ! kill(bp->pid, signal); } curr = next; *************** *** 3491,3496 **** --- 3492,3499 ---- char *p; int i; char cmdLine[MAXPGPATH]; + HANDLE childHandleCopy; + HANDLE waiterThread; /* Format the cmd line */ snprintf(cmdLine,sizeof(cmdLine),"%s",path); *************** *** 3522,3528 **** if (!IsUnderPostmaster) /* We are the Postmaster creating a child... */ win32_AddChild(pi.dwProcessId,pi.hProcess); ! else CloseHandle(pi.hProcess); CloseHandle(pi.hThread); --- 3525,3547 ---- if (!IsUnderPostmaster) /* We are the Postmaster creating a child... */ win32_AddChild(pi.dwProcessId,pi.hProcess); ! ! if (!DuplicateHandle(GetCurrentProcess(), ! pi.hProcess, ! GetCurrentProcess(), ! &childHandleCopy, ! 0, ! FALSE, ! DUPLICATE_SAME_ACCESS)) ! ereport(FATAL, ! (errmsg_internal("failed to duplicate child handle: %i",GetLastError()))); ! waiterThread = CreateThread(NULL, 64*1024, win32_sigchld_waiter, (LPVOID)childHandleCopy, 0, NULL); ! if (!waiterThread) ! ereport(FATAL, ! (errmsg_internal("failed to create sigchld waiter thread: %i",GetLastError()))); ! CloseHandle(waiterThread); ! ! if (IsUnderPostmaster) CloseHandle(pi.hProcess); CloseHandle(pi.hThread); *************** *** 3566,3573 **** /* Swap last entry into the "removed" one */ --win32_numChildren; ! win32_childPIDArray[win32_numChildren] = win32_childPIDArray[i]; ! win32_childHNDArray[win32_numChildren] = win32_childHNDArray[i]; return; } } --- 3585,3592 ---- /* Swap last entry into the "removed" one */ --win32_numChildren; ! win32_childPIDArray[i] = win32_childPIDArray[win32_numChildren]; ! win32_childHNDArray[i] = win32_childHNDArray[win32_numChildren]; return; } } *************** *** 3597,3604 **** { case WAIT_FAILED: ereport(ERROR, ! (errmsg_internal("failed to wait on %d children", ! win32_numChildren))); /* Fall through to WAIT_TIMEOUTs return */ case WAIT_TIMEOUT: --- 3616,3623 ---- { case WAIT_FAILED: ereport(ERROR, ! (errmsg_internal("failed to wait on %d children: %i", ! win32_numChildren,GetLastError()))); /* Fall through to WAIT_TIMEOUTs return */ case WAIT_TIMEOUT: *************** *** 3624,3629 **** --- 3643,3662 ---- /* No children */ return -1; + } + + /* Note! Code belows executes on separate threads, one for + each child process created */ + static DWORD WINAPI win32_sigchld_waiter(LPVOID param) { + HANDLE procHandle = (HANDLE)param; + + DWORD r = WaitForSingleObject(procHandle, INFINITE); + if (r == WAIT_OBJECT_0) + pg_queue_signal(SIGCHLD); + else + fprintf(stderr,"ERROR: Failed to wait on child process handle: %i\n",GetLastError()); + CloseHandle(procHandle); + return 0; } #endif diff -cr postgresql-snapshot-030203/src/backend/storage/ipc/pmsignal.c postgresql-win32-mha/src/backend/storage/ipc/pmsignal.c *** postgresql-snapshot-030203/src/backend/storage/ipc/pmsignal.c Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/backend/storage/ipc/pmsignal.c Wed Feb 4 00:29:27 2004 *************** *** 20,26 **** #include "miscadmin.h" #include "storage/pmsignal.h" #include "storage/shmem.h" - #include "libpq/pqsignal.h" /* --- 20,25 ---- *************** *** 65,71 **** /* Atomically set the proper flag */ PMSignalFlags[reason] = true; /* Send signal to postmaster */ ! pqkill(PostmasterPid, SIGUSR1); } /* --- 64,70 ---- /* Atomically set the proper flag */ PMSignalFlags[reason] = true; /* Send signal to postmaster */ ! kill(PostmasterPid, SIGUSR1); } /* diff -cr postgresql-snapshot-030203/src/backend/storage/lmgr/proc.c postgresql-win32-mha/src/backend/storage/lmgr/proc.c *** postgresql-snapshot-030203/src/backend/storage/lmgr/proc.c Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/backend/storage/lmgr/proc.c Wed Feb 4 00:29:27 2004 *************** *** 51,57 **** #include "storage/proc.h" #include "storage/sinval.h" #include "storage/spin.h" - #include "libpq/pqsignal.h" /* GUC variables */ int DeadlockTimeout = 1000; --- 51,56 ---- *************** *** 1131,1137 **** { /* Time to die */ statement_timeout_active = false; ! pqkill(MyProcPid, SIGINT); } else { --- 1130,1136 ---- { /* Time to die */ statement_timeout_active = false; ! kill(MyProcPid, SIGINT); } else { diff -cr postgresql-snapshot-030203/src/backend/utils/init/miscinit.c postgresql-win32-mha/src/backend/utils/init/miscinit.c *** postgresql-snapshot-030203/src/backend/utils/init/miscinit.c Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/backend/utils/init/miscinit.c Wed Feb 4 00:29:27 2004 *************** *** 32,38 **** #include "catalog/catname.h" #include "catalog/pg_shadow.h" #include "libpq/libpq-be.h" - #include "libpq/pqsignal.h" #include "miscadmin.h" #include "storage/ipc.h" #include "storage/pg_shmem.h" --- 32,37 ---- *************** *** 532,538 **** */ if (other_pid != my_pid) { ! if (pqkill(other_pid, 0) == 0 || (errno != ESRCH #ifdef __BEOS__ && errno != EINVAL --- 531,537 ---- */ if (other_pid != my_pid) { ! if (kill(other_pid, 0) == 0 || (errno != ESRCH #ifdef __BEOS__ && errno != EINVAL diff -cr postgresql-snapshot-030203/src/include/libpq/pqsignal.h postgresql-win32-mha/src/include/libpq/pqsignal.h *** postgresql-snapshot-030203/src/include/libpq/pqsignal.h Tue Jan 27 01:45:26 2004 --- postgresql-win32-mha/src/include/libpq/pqsignal.h Wed Feb 4 21:11:01 2004 *************** *** 22,36 **** #include #endif - #ifndef WIN32 - #define pqkill(pid,sig) kill(pid,sig) - #define pqsigsetmask(mask) sigsetmask(mask) - #else - int pqkill(int pid, int sig); - int pqsigsetmask(int mask); - #endif - - #ifdef HAVE_SIGPROCMASK extern sigset_t UnBlockSig, BlockSig, --- 22,27 ---- *************** *** 42,48 **** BlockSig, AuthBlockSig; ! #define PG_SETMASK(mask) pqsigsetmask(*((int*)(mask))) #endif typedef void (*pqsigfunc) (int); --- 33,44 ---- BlockSig, AuthBlockSig; ! #ifndef WIN32 ! #define PG_SETMASK(mask) sigsetmask(*((int*)(mask))) ! #else ! #define PG_SETMASK(mask) pqsigsetmask(*((int*)(mask))) ! int pqsigsetmask(int mask); ! #endif #endif typedef void (*pqsigfunc) (int); *************** *** 50,55 **** --- 46,52 ---- extern void pqinitmask(void); extern pqsigfunc pqsignal(int signo, pqsigfunc func); + extern void pg_queue_signal(int signum); #ifdef WIN32 #define sigmask(sig) ( 1 << (sig-1) ) *************** *** 58,162 **** extern HANDLE pgwin32_main_thread_handle; #define PG_POLL_SIGNALS() WaitForSingleObjectEx(pgwin32_main_thread_handle,0,TRUE); ! /* Define signal numbers. Override system values, since they are not ! complete anyway */ ! ! #undef SIGHUP ! #define SIGHUP 1 /* hangup */ ! ! #undef SIGINT ! #define SIGINT 2 /* interrupt */ ! ! #undef SIGQUIT ! #define SIGQUIT 3 /* quit */ ! ! #undef SIGILL ! #define SIGILL 4 /* illegal instruction (not reset when caught) */ ! ! #undef SIGTRAP ! #define SIGTRAP 5 /* trace trap (not reset when caught) */ ! ! #undef SIGABRT ! #define SIGABRT 6 /* abort(void) */ ! ! #undef SIGIOT ! #define SIGIOT SIGABRT /* compatibility */ ! ! #undef SIGEMT ! #define SIGEMT 7 /* EMT instruction */ ! ! #undef SIGFPE ! #define SIGFPE 8 /* floating point exception */ ! ! #undef SIGKILL ! #define SIGKILL 9 /* kill (cannot be caught or ignored) */ ! ! #undef SIGBUS ! #define SIGBUS 10 /* bus error */ ! ! #undef SIGSEGV ! #define SIGSEGV 11 /* segmentation violation */ ! ! #undef SIGSYS ! #define SIGSYS 12 /* non-existent system call invoked */ ! ! #undef SIGSYS ! #define SIGPIPE 13 /* write on a pipe with no one to read it */ ! ! #undef SIGALRM ! #define SIGALRM 14 /* alarm clock */ ! ! #undef SIGTERM ! #define SIGTERM 15 /* software termination signal from kill */ ! ! #undef SIGURG ! #define SIGURG 16 /* urgent condition on IO channel */ ! ! #undef SIGSTOP ! #define SIGSTOP 17 /* sendable stop signal not from tty */ ! ! #undef SIGTSTP ! #define SIGTSTP 18 /* stop signal from tty */ ! ! #undef SIGCONT ! #define SIGCONT 19 /* continue a stopped process */ ! ! #undef SIGCHLD ! #define SIGCHLD 20 /* to parent on child stop or exit */ ! ! #undef SIGTTIN ! #define SIGTTIN 21 /* to readers pgrp upon background tty read */ ! ! #undef SIGTTOU ! #define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ ! ! #undef SIGIO ! #define SIGIO 23 /* input/output possible signal */ ! ! #undef SIGXCPU ! #define SIGXCPU 24 /* exceeded CPU time limit */ ! ! #undef SIGXFSZ ! #define SIGXFSZ 25 /* exceeded file size limit */ ! ! #undef SIGVTALR ! #define SIGVTALRM 26 /* virtual time alarm */ ! ! #undef SIGPROF ! #define SIGPROF 27 /* profiling time alarm */ ! ! #undef SIGWINCH ! #define SIGWINCH 28 /* window size changes */ ! ! #undef SIGINFO ! #define SIGINFO 29 /* information request */ ! ! #undef SIGUSR1 ! #define SIGUSR1 30 /* user defined signal 1 */ ! ! #undef SIGUSR2 ! #define SIGUSR2 31 /* user defined signal 2 */ ! #undef SIG_DFL #undef SIG_ERR #undef SIG_IGN --- 55,61 ---- extern HANDLE pgwin32_main_thread_handle; #define PG_POLL_SIGNALS() WaitForSingleObjectEx(pgwin32_main_thread_handle,0,TRUE); ! /* Signal function return values */ #undef SIG_DFL #undef SIG_ERR #undef SIG_IGN diff -cr postgresql-snapshot-030203/src/include/port/win32.h postgresql-win32-mha/src/include/port/win32.h *** postgresql-snapshot-030203/src/include/port/win32.h Mon Jan 26 23:59:54 2004 --- postgresql-win32-mha/src/include/port/win32.h Wed Feb 4 22:17:40 2004 *************** *** 5,10 **** --- 5,11 ---- #undef ERROR #include + #include #undef near /* Must be here to avoid conflicting with prototype in windows.h */ *************** *** 99,104 **** --- 100,112 ---- int semop(int semId, struct sembuf * sops, int flag); #define sleep(sec) (Sleep(sec * 1000), /* no return value */ 0) + + + #ifndef FRONTEND + /* In libpq/pqsignal.c */ + #define kill(pid,sig) pqkill(pid,sig) + int pqkill(int pid, int sig); + #endif /* Some extra signals */ #define SIGHUP 1