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 00:29:27 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 */ + } } *************** *** 427,432 **** --- 428,447 ---- 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) { + 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/port/win32/Makefile postgresql-win32-mha/src/backend/port/win32/Makefile *** postgresql-snapshot-030203/src/backend/port/win32/Makefile Sat Nov 29 20:51:54 2003 --- postgresql-win32-mha/src/backend/port/win32/Makefile Wed Feb 4 00:29:27 2004 *************** *** 12,18 **** top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = sema.o shmem.o all: SUBSYS.o --- 12,18 ---- top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = sema.o shmem.o select.o all: SUBSYS.o 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 00:29:27 2004 *************** *** 308,317 **** --- 308,320 ---- 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_sender(LPVOID param); static pid_t *win32_childPIDArray; static HANDLE *win32_childHNDArray; static unsigned long win32_numChildren = 0; + static HANDLE win32_sigchld_event1; + static HANDLE win32_sigchld_event2; #endif static pid_t Backend_forkexec(Port *port); *************** *** 850,861 **** /* 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, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); #endif /* --- 853,872 ---- /* 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, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); + win32_sigchld_event1 = CreateEvent(NULL, FALSE, FALSE, NULL); + win32_sigchld_event2 = CreateEvent(NULL, FALSE, FALSE, NULL); + if (win32_sigchld_event1 == NULL || win32_sigchld_event2 == NULL) + ereport(FATAL, + (errmsg_internal("failed to create sigchld events: %i!",GetLastError()))); + if (CreateThread(NULL, 0, win32_sigchld_sender, NULL, 0, NULL) == NULL) + ereport(FATAL, + (errmsg_internal("failed to create sigchld thread: %i",GetLastError()))); #endif /* *************** *** 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 */ --- 1577,1583 ---- 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); --- 1749,1755 ---- * 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; --- 1783,1789 ---- * 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, --- 1817,1823 ---- * 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); --- 1865,1877 ---- * 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 --- 2141,2147 ---- (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; --- 2236,2242 ---- (errmsg_internal("sending signal %d to process %d", signal, (int) bp->pid))); ! kill(bp->pid, signal); } curr = next; *************** *** 3547,3552 **** --- 3558,3567 ---- win32_childPIDArray[win32_numChildren] = pid; win32_childHNDArray[win32_numChildren] = handle; ++win32_numChildren; + SetEvent(win32_sigchld_event1); + if (WaitForSingleObjectEx(win32_sigchld_event2, INFINITE, FALSE) != WAIT_OBJECT_0) + ereport(FATAL, + (errmsg_internal("failed to wait for sigchld event: %i",GetLastError()))); } else /* FIXME: [fork/exec] some sort of error */ *************** *** 3568,3573 **** --- 3583,3592 ---- --win32_numChildren; win32_childPIDArray[win32_numChildren] = win32_childPIDArray[i]; win32_childHNDArray[win32_numChildren] = win32_childHNDArray[i]; + SetEvent(win32_sigchld_event1); + if (WaitForSingleObjectEx(win32_sigchld_event2, INFINITE, FALSE) != WAIT_OBJECT_0) + ereport(FATAL, + (errmsg_internal("failed to wait for sigchld event: %i",GetLastError()))); return; } } *************** *** 3626,3629 **** --- 3645,3700 ---- return -1; } + + /* NOTE! Functions below execute on a separate thread! */ + + /* Grab a new copy of the handle array */ + static int win32_sigchld_sender_copy_handles(HANDLE *listen_handles) { + int numhandles; + memcpy((char *)&listen_handles[1], (char *)win32_childHNDArray, win32_numChildren * sizeof(HANDLE)); + numhandles = win32_numChildren; + SetEvent(win32_sigchld_event2); + return numhandles; + } + + static DWORD WINAPI win32_sigchld_sender(LPVOID param) { + int numhandles = 0; + HANDLE *listen_handles = (HANDLE *)malloc(NUM_BACKENDARRAY_ELEMS*sizeof(HANDLE)); + if (!listen_handles) { + fprintf(stderr,"ERROR: failed to allocate memory for listen handles!\n"); + return 0; + } + + listen_handles[0] = win32_sigchld_event1; + + for (;;) { + int r; + + /* First look just at the event in case we have to update the + list of handles */ + if (WaitForSingleObjectEx(win32_sigchld_event1, 0, FALSE) == WAIT_OBJECT_0) { + numhandles = win32_sigchld_sender_copy_handles(listen_handles); + continue; + } + r = WaitForMultipleObjectsEx(numhandles+1, listen_handles, FALSE, INFINITE, FALSE); + if (r == WAIT_OBJECT_0) { + numhandles = win32_sigchld_sender_copy_handles(listen_handles); + } + else if (r == WAIT_FAILED) { + fprintf(stderr,"ERROR: WaitForMultipleObjectsEx() failed in sigchld sender: %i\n",GetLastError()); + Sleep(5000); + continue; + } + else if (r == WAIT_IO_COMPLETION || r == WAIT_TIMEOUT) { + /* This really should not happen. But catch it just in case. */ + continue; + } + else { + /* Send ourself SIGCHLD */ + kill(GetCurrentProcessId(),SIGCHLD); + } + } + + 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 00:29:27 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); *************** *** 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 --- 54,60 ---- 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 00:29:27 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,116 ---- 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); + + /* In backend/port/win32/select.c */ + #define select(a,b,c,d,e) pqselect(a,b,c,d,e) + int pqselect(int n, fd_set *r, fd_set *w, fd_set *e, const struct timeval *t); + #endif /* Some extra signals */ #define SIGHUP 1