From f4921e5ca38aac1214854e7226e8bb3291d60485 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Mon, 26 Jan 2004 22:51:56 +0000
Subject: [PATCH] Attached is a patch that fixes some trivial typos and
 alignment.  Please apply.

Alvaro Herrera
---
 src/backend/access/transam/xact.c   |  12 +-
 src/backend/postmaster/pgstat.c     |   6 +-
 src/backend/postmaster/postmaster.c | 255 +++++++++++++++++++++++++---
 src/backend/storage/ipc/ipci.c      |  12 +-
 src/backend/storage/ipc/pmsignal.c  |   6 +-
 src/backend/tcop/postgres.c         |   6 +-
 src/backend/utils/init/globals.c    |   4 +-
 src/include/access/xact.h           |  14 +-
 src/include/miscadmin.h             |   9 +-
 src/include/port/win32.h            |   8 +-
 10 files changed, 279 insertions(+), 53 deletions(-)

diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 56ecf9d2f43..d5f357bc5ff 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.160 2004/01/09 21:08:46 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.161 2004/01/26 22:51:55 momjian Exp $
  *
  * NOTES
  *		Transaction aborts can now occur two ways:
@@ -87,7 +87,7 @@
  *
  *		Support for transaction blocks is provided via the functions:
  *
- *				StartTransactionBlock
+ *				BeginTransactionBlock
  *				CommitTransactionBlock
  *				AbortTransactionBlock
  *
@@ -108,7 +108,7 @@
  *
  *			/	StartTransactionCommand();
  *		1) /	ProcessUtility();				<< begin
- *		   \		StartTransactionBlock();
+ *		   \		BeginTransactionBlock();
  *			\	CommitTransactionCommand();
  *
  *			/	StartTransactionCommand();
@@ -127,7 +127,7 @@
  *		The point of this example is to demonstrate the need for
  *		StartTransactionCommand() and CommitTransactionCommand() to
  *		be state smart -- they should do nothing in between the calls
- *		to StartTransactionBlock() and EndTransactionBlock() and
+ *		to BeginTransactionBlock() and EndTransactionBlock() and
  *		outside these calls they need to do normal start/commit
  *		processing.
  *
@@ -399,7 +399,7 @@ CommandIdIsCurrentCommandId(CommandId cid)
 {
 	TransactionState s = CurrentTransactionState;
 
-	return (cid == s->commandId) ? true : false;
+	return (cid == s->commandId);
 }
 
 
@@ -860,7 +860,7 @@ StartTransaction(void)
 	AtStart_Locks();
 
 	/*
-	 * Tell the trigger manager to we're starting a transaction
+	 * Tell the trigger manager we're starting a transaction
 	 */
 	DeferredTriggerBeginXact();
 
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 6b9b8ac1bc8..14178553d23 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
  *
  *	Copyright (c) 2001-2003, PostgreSQL Global Development Group
  *
- *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.53 2004/01/11 03:49:31 momjian Exp $
+ *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.54 2004/01/26 22:51:55 momjian Exp $
  * ----------
  */
 #include "postgres.h"
@@ -147,7 +147,7 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
 #define piperead(a,b,c)		read(a,b,c)
 #define pipewrite(a,b,c)	write(a,b,c)
 #else
-/* pgpipe() is in /src/port */
+extern int pgpipe(int handles[2]); /* pgpipe() is in /src/port */
 #define piperead(a,b,c)		recv(a,b,c,0)
 #define pipewrite(a,b,c)	send(a,b,c,0)
 #endif
@@ -322,7 +322,7 @@ pgstat_init(void)
 	/*
 	 * Create the pipe that controls the statistics collector shutdown
 	 */
-	if (pipe(pgStatPmPipe) < 0)
+	if (pgpipe(pgStatPmPipe) < 0)
 	{
 		ereport(LOG,
 				(errcode_for_socket_access(),
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index dd5f55c5adb..aff21186a0e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.359 2004/01/26 22:35:32 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.360 2004/01/26 22:51:55 momjian Exp $
  *
  * NOTES
  *
@@ -141,6 +141,11 @@ typedef struct bkend
 
 static Dllist *BackendList;
 
+#ifdef EXEC_BACKEND
+#define NUM_BACKENDARRAY_ELEMS (2*MaxBackends)
+static Backend *ShmemBackendArray;
+#endif
+
 /* The socket number we are listening for connections on */
 int			PostPortNumber;
 char	   *UnixSocketDir;
@@ -299,6 +304,14 @@ __attribute__((format(printf, 1, 2)));
 #ifdef EXEC_BACKEND
 #ifdef WIN32
 pid_t win32_forkexec(const char* path, char *argv[]);
+
+static void  win32_AddChild(pid_t pid, HANDLE handle);
+static void  win32_RemoveChild(pid_t pid);
+static pid_t win32_waitpid(int *exitstatus);
+
+static pid_t  *win32_childPIDArray;
+static HANDLE *win32_childHNDArray;
+static unsigned long win32_numChildren = 0;
 #endif
 
 static pid_t Backend_forkexec(Port *port);
@@ -306,6 +319,11 @@ static pid_t Backend_forkexec(Port *port);
 static unsigned long tmpBackendFileNum = 0;
 void read_backend_variables(unsigned long id, Port *port);
 static bool write_backend_variables(Port *port);
+
+size_t 		ShmemBackendArraySize(void);
+void 		ShmemBackendArrayAllocation(void);
+static void	ShmemBackendArrayAdd(Backend *bn);
+static void ShmemBackendArrayRemove(pid_t pid);
 #endif
 
 #define StartupDataBase()		SSDataBase(BS_XLOG_STARTUP)
@@ -430,7 +448,7 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	umask((mode_t) 0077);
 
-	MyProcPid = getpid();
+	MyProcPid = PostmasterPid = getpid();
 
 	/*
 	 * Fire up essential subsystems: memory management
@@ -825,6 +843,21 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	BackendList = DLNewList();
 
+#ifdef WIN32
+	/*
+	 * Initialize the child pid/HANDLE arrays
+	 */
+	/* 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
+
 	/*
 	 * Record postmaster options.  We delay this till now to avoid
 	 * recording bogus options (eg, NBuffers too high for available
@@ -1257,11 +1290,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
 
 	if (proto == CANCEL_REQUEST_CODE)
 	{
-#ifdef EXEC_BACKEND
-		abort(); /* FIXME: [fork/exec] Whoops. Not handled... yet */
-#else
 		processCancelRequest(port, buf);
-#endif
 		return 127;				/* XXX */
 	}
 
@@ -1494,8 +1523,12 @@ processCancelRequest(Port *port, void *pkt)
 	CancelRequestPacket *canc = (CancelRequestPacket *) pkt;
 	int			backendPID;
 	long		cancelAuthCode;
-	Dlelem	   *curr;
 	Backend    *bp;
+#ifndef EXEC_BACKEND
+	Dlelem	   *curr;
+#else
+	int i;
+#endif
 
 	backendPID = (int) ntohl(canc->backendPID);
 	cancelAuthCode = (long) ntohl(canc->cancelAuthCode);
@@ -1514,16 +1547,17 @@ processCancelRequest(Port *port, void *pkt)
 								 backendPID)));
 		return;
 	}
-#ifdef EXEC_BACKEND
-	else
-		AttachSharedMemoryAndSemaphores();
-#endif
 
 	/* See if we have a matching backend */
-
+#ifndef EXEC_BACKEND
 	for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
 	{
 		bp = (Backend *) DLE_VAL(curr);
+#else
+	for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
+	{
+		bp = (Backend*) &ShmemBackendArray[i];
+#endif
 		if (bp->pid == backendPID)
 		{
 			if (bp->cancel_key == cancelAuthCode)
@@ -1846,14 +1880,12 @@ reaper(SIGNAL_ARGS)
 {
 	int			save_errno = errno;
 
-#ifdef WIN32
-#warning fix waidpid for Win32
-#else
 #ifdef HAVE_WAITPID
 	int			status;			/* backend exit status */
-
 #else
+#ifndef WIN32
 	union wait	status;			/* backend exit status */
+#endif
 #endif
 	int			exitstatus;
 	int			pid;			/* process id of dead backend */
@@ -1867,9 +1899,21 @@ reaper(SIGNAL_ARGS)
 	{
 		exitstatus = status;
 #else
+#ifndef WIN32
 	while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
 	{
 		exitstatus = status.w_status;
+#else
+	while ((pid = win32_waitpid(&exitstatus)) > 0)
+	{
+		/*
+		 * We need to do this here, and not in CleanupProc, since this
+		 * is to be called on all children when we are done with them.
+		 * Could move to LogChildExit, but that seems like asking for
+		 * future trouble...
+		 */
+		win32_RemoveChild(pid);
+#endif
 #endif
 
 		/*
@@ -1957,7 +2001,6 @@ reaper(SIGNAL_ARGS)
 		CleanupProc(pid, exitstatus);
 
 	}							/* loop over pending child-death reports */
-#endif
 
 	if (FatalError)
 	{
@@ -2022,6 +2065,9 @@ CleanupProc(int pid,
 			bp = (Backend *) DLE_VAL(curr);
 			if (bp->pid == pid)
 			{
+#ifdef EXEC_BACKEND
+				ShmemBackendArrayRemove(bp->pid);
+#endif
 				DLRemove(curr);
 				free(bp);
 				DLFreeElem(curr);
@@ -2092,6 +2138,9 @@ CleanupProc(int pid,
 			/*
 			 * Found entry for freshly-dead backend, so remove it.
 			 */
+#ifdef EXEC_BACKEND
+			ShmemBackendArrayRemove(bp->pid);
+#endif
 			DLRemove(curr);
 			free(bp);
 			DLFreeElem(curr);
@@ -2296,6 +2345,9 @@ BackendStartup(Port *port)
 	 */
 	bn->pid = pid;
 	bn->cancel_key = MyCancelKey;
+#ifdef EXEC_BACKEND
+	ShmemBackendArrayAdd(bn);
+#endif
 	DLAddHead(BackendList, DLNewElem(bn));
 
 	return STATUS_OK;
@@ -2642,6 +2694,9 @@ SubPostmasterMain(int argc, char* argv[])
 	memset((void*)&port, 0, sizeof(Port));
 	Assert(argc == 2);
 
+	/* Do this sooner rather than later... */
+	IsUnderPostmaster = true;	/* we are a postmaster subprocess now */
+
 	/* Setup global context */
 	MemoryContextInit();
 	InitializeGUCOptions();
@@ -2661,6 +2716,9 @@ SubPostmasterMain(int argc, char* argv[])
 	load_user();
 	load_group();
 
+	/* Attach process to shared segments */
+	AttachSharedMemoryAndSemaphores();
+
 	/* Run backend */
 	proc_exit(BackendRun(&port));
 }
@@ -3129,6 +3187,9 @@ SSDataBase(int xlop)
 
 		bn->pid = pid;
 		bn->cancel_key = PostmasterRandom();
+#ifdef EXEC_BACKEND
+		ShmemBackendArrayAdd(bn);
+#endif
 		DLAddHead(BackendList, DLNewElem(bn));
 
 		/*
@@ -3278,6 +3339,7 @@ write_backend_variables(Port *port)
 	write_var(ShmemIndexLock,fp);
 	write_var(ShmemVariableCache,fp);
 	write_var(ShmemIndexAlloc,fp);
+	write_var(ShmemBackendArray,fp);
 
 	write_var(LWLockArray,fp);
 	write_var(ProcStructLock,fp);
@@ -3285,6 +3347,7 @@ write_backend_variables(Port *port)
 
 	write_var(PreAuthDelay,fp);
 	write_var(debug_flag,fp);
+	write_var(PostmasterPid,fp);
 
 	/* Release file */
 	if (FreeFile(fp))
@@ -3338,6 +3401,7 @@ read_backend_variables(unsigned long id, Port *port)
 	read_var(ShmemIndexLock,fp);
 	read_var(ShmemVariableCache,fp);
 	read_var(ShmemIndexAlloc,fp);
+	read_var(ShmemBackendArray,fp);
 
 	read_var(LWLockArray,fp);
 	read_var(ProcStructLock,fp);
@@ -3345,6 +3409,7 @@ read_backend_variables(unsigned long id, Port *port)
 
 	read_var(PreAuthDelay,fp);
 	read_var(debug_flag,fp);
+	read_var(PostmasterPid,fp);
 
 	/* Release file */
 	FreeFile(fp);
@@ -3354,6 +3419,55 @@ read_backend_variables(unsigned long id, Port *port)
 				 errmsg("could not remove file \"%s\": %m", filename)));
 }
 
+
+size_t ShmemBackendArraySize(void)
+{
+	return (NUM_BACKENDARRAY_ELEMS*sizeof(Backend));
+}
+
+void ShmemBackendArrayAllocation(void)
+{
+	size_t size = ShmemBackendArraySize();
+	ShmemBackendArray = (Backend*)ShmemAlloc(size);
+	memset(ShmemBackendArray, 0, size);
+}
+
+static void ShmemBackendArrayAdd(Backend *bn)
+{
+	int i;
+	for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
+	{
+		/* Find an empty slot */
+		if (ShmemBackendArray[i].pid == 0)
+		{
+			ShmemBackendArray[i] = *bn;
+			return;
+		}
+	}
+
+	/* FIXME: [fork/exec] some sort of error */
+	abort();
+}
+
+static void ShmemBackendArrayRemove(pid_t pid)
+{
+	int i;
+	for (i = 0; i < NUM_BACKENDARRAY_ELEMS; i++)
+	{
+		if (ShmemBackendArray[i].pid == pid)
+		{
+			/* Mark the slot as empty */
+			ShmemBackendArray[i].pid = 0;
+			return;
+		}
+	}
+
+	/* Something stronger than WARNING here? */
+	ereport(WARNING,
+			(errmsg_internal("unable to find backend entry with pid %d",
+							 pid)));
+}
+
 #endif
 
 #ifdef WIN32
@@ -3393,14 +3507,111 @@ pid_t win32_forkexec(const char* path, char *argv[])
 		return -1;
 	}
 
-	/*
-	   FIXME: [fork/exec] we might need to keep the following handle/s,
-	   depending on how we implement signalling.
-	*/
-	CloseHandle(pi.hProcess);
+	if (!IsUnderPostmaster)
+		/* We are the Postmaster creating a child... */
+		win32_AddChild(pi.dwProcessId,pi.hProcess);
+	else
+		CloseHandle(pi.hProcess);
 	CloseHandle(pi.hThread);
 
 	return pi.dwProcessId;
 }
 
+/*
+ * Note: The following three functions must not be interrupted (eg. by signals).
+ *  As the Postgres Win32 signalling architecture (currently) requires polling,
+ *  or APC checking functions which aren't used here, this is not an issue.
+ *
+ *  We keep two separate arrays, instead of a single array of pid/HANDLE structs,
+ *  to avoid having to re-create a handle array for WaitForMultipleObjects on
+ *  each call to win32_waitpid.
+ */
+
+static void win32_AddChild(pid_t pid, HANDLE handle)
+{
+	Assert(win32_childPIDArray && win32_childHNDArray);
+	if (win32_numChildren < NUM_BACKENDARRAY_ELEMS)
+	{
+		win32_childPIDArray[win32_numChildren] = pid;
+		win32_childHNDArray[win32_numChildren] = handle;
+		++win32_numChildren;
+	}
+	else
+		/* FIXME: [fork/exec] some sort of error */
+		abort();
+}
+
+static void win32_RemoveChild(pid_t pid)
+{
+	int i;
+	Assert(win32_childPIDArray && win32_childHNDArray);
+
+	for (i = 0; i < win32_numChildren; i++)
+	{
+		if (win32_childPIDArray[i] == pid)
+		{
+			CloseHandle(win32_childHNDArray[i]);
+
+			/* Swap last entry into the "removed" one */
+			--win32_numChildren;
+			win32_childPIDArray[win32_numChildren] = win32_childPIDArray[i];
+			win32_childHNDArray[win32_numChildren] = win32_childHNDArray[i];
+			return;
+		}
+	}
+
+	/* Something stronger than WARNING here? */
+	ereport(WARNING,
+			(errmsg_internal("unable to find child entry with pid %d",
+							 pid)));
+}
+
+static pid_t win32_waitpid(int *exitstatus)
+{
+	Assert(win32_childPIDArray && win32_childHNDArray);
+	elog(DEBUG3,"waiting on %d children",win32_numChildren);
+
+	if (win32_numChildren > 0)
+	{
+		/*
+		 * Note: Do NOT use WaitForMultipleObjectsEx, as we don't
+		 * want to run queued APCs here.
+		 */
+		int index;
+		DWORD exitCode;
+		DWORD ret = WaitForMultipleObjects(win32_numChildren,win32_childHNDArray,FALSE,0);
+
+		switch (ret)
+		{
+			case WAIT_FAILED:
+				ereport(ERROR,
+						(errmsg_internal("failed to wait on %d children",
+										 win32_numChildren)));
+				/* Fall through to WAIT_TIMEOUTs return */
+
+			case WAIT_TIMEOUT:
+				/* No children have finished */
+				return -1;
+
+			default:
+				/* Get the exit code, and return the PID of, the respective process */
+				index = ret-WAIT_OBJECT_0;
+				Assert(index >= 0 && index < win32_numChildren);
+				if (!GetExitCodeProcess(win32_childHNDArray[index],&exitCode))
+					/*
+					 * If we get this far, this should never happen, but, then again...
+					 * No choice other than to assume a catastrophic failure.
+					 */
+					ereport(FATAL,
+							(errmsg_internal("failed to get exit code for child %d",
+											 win32_childPIDArray[index])));
+				*exitstatus = (int)exitCode;
+				return win32_childPIDArray[index];
+		}
+	}
+
+	/* No children */
+	return -1;
+}
+
 #endif
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index eaf22a095f1..888dd7aeda7 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.60 2003/12/20 17:31:21 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.61 2004/01/26 22:51:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
 	size += LWLockShmemSize();
 	size += SInvalShmemSize(maxBackends);
 	size += FreeSpaceShmemSize();
+#ifdef EXEC_BACKEND
+	size += ShmemBackendArraySize();
+#endif
 #ifdef STABLE_MEMORY_STORAGE
 	size += MMShmemSize();
 #endif
@@ -132,6 +135,13 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
 	 * Set up child-to-postmaster signaling mechanism
 	 */
 	PMSignalInit();
+
+#ifdef EXEC_BACKEND
+	/*
+	 * Alloc the win32 shared backend array
+	 */
+	ShmemBackendArrayAllocation();
+#endif
 }
 
 
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 137e864aa50..2795475cc76 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.8 2004/01/11 03:49:31 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.9 2004/01/26 22:51:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,8 +63,8 @@ SendPostmasterSignal(PMSignalReason reason)
 		return;
 	/* Atomically set the proper flag */
 	PMSignalFlags[reason] = true;
-	/* Send signal to postmaster (assume it is our direct parent) */
-	kill(getppid(), SIGUSR1);
+	/* Send signal to postmaster */
+	kill(PostmasterPid, SIGUSR1);
 }
 
 /*
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index b99d6b4fe6f..4e4066a72d9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.383 2004/01/06 23:15:22 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.384 2004/01/26 22:51:56 momjian Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -2535,9 +2535,7 @@ PostgresMain(int argc, char *argv[], const char *username)
 					 errmsg("invalid command-line arguments for server process"),
 					 errhint("Try \"%s --help\" for more information.", argv[0])));
 		}
-#ifdef EXEC_BACKEND
-		AttachSharedMemoryAndSemaphores();
-#endif
+
 		XLOGPathInit();
 
 		BaseInit();
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 72c9be43987..c5d4282007f 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.77 2004/01/06 17:36:31 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.78 2004/01/26 22:51:56 momjian Exp $
  *
  * NOTES
  *	  Globals used all over the place should be declared here and not
@@ -53,6 +53,8 @@ BackendId	MyBackendId;
 char	   *DatabasePath = NULL;
 Oid			MyDatabaseId = InvalidOid;
 
+pid_t PostmasterPid = 0;
+
 /* these are initialized for the bootstrap/standalone case: */
 bool		IsPostmasterEnvironment = false;
 bool		IsUnderPostmaster = false;
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index b7012acdb8b..54ae24e53f9 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.59 2003/11/29 22:40:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/access/xact.h,v 1.60 2004/01/26 22:51:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -75,12 +75,12 @@ typedef void (*EOXactCallback) (bool isCommit, void *arg);
  */
 typedef struct TransactionStateData
 {
-	TransactionId transactionIdData;
-	CommandId	commandId;
-	AbsoluteTime startTime;
-	int			startTimeUsec;
-	TransState	state;
-	TBlockState blockState;
+	TransactionId	transactionIdData;
+	CommandId		commandId;
+	AbsoluteTime	startTime;
+	int				startTimeUsec;
+	TransState		state;
+	TBlockState		blockState;
 } TransactionStateData;
 
 typedef TransactionStateData *TransactionState;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 67be1137fc9..c14882e6218 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.145 2004/01/22 20:57:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.146 2004/01/26 22:51:56 momjian Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to
@@ -109,10 +109,14 @@ do { \
 #else
 #define PG_USLEEP(_usec) \
 do { \
-	Sleep(_usec < 500) ? 1 : (_usec+500)/ 1000); \
+	Sleep((_usec) < 500 ? 1 : ((_usec)+500)/ 1000); \
 } while(0)
 #endif
 
+#ifdef WIN32
+#define ftruncate(a,b)	chsize(a,b)
+#endif
+
 /*****************************************************************************
  *	  globals.h --															 *
  *****************************************************************************/
@@ -132,6 +136,7 @@ extern void ClosePostmasterPorts(bool pgstat_too);
 /*
  * from utils/init/globals.c
  */
+extern pid_t PostmasterPid;
 extern bool IsPostmasterEnvironment;
 extern bool IsUnderPostmaster;
 
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index a9aa6182161..3a34a70b06f 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.13 2003/11/29 19:52:08 pgsql Exp $ */
+/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.14 2004/01/26 22:51:56 momjian Exp $ */
 
 /* undefine and redefine after #include */
 #undef mkdir
@@ -15,7 +15,7 @@
 #define NOFILE		  100
 
 /* defines for dynamic linking on Win32 platform */
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__) || defined(__MINGW32__)
 
 #if __GNUC__ && ! defined (__declspec)
 #error You need egcs 1.1 or newer for compiling!
@@ -27,7 +27,7 @@
 #define DLLIMPORT __declspec (dllimport)
 #endif
 
-#elif defined(WIN32) && defined(_MSC_VER)		/* not CYGWIN */
+#elif defined(WIN32) && defined(_MSC_VER)		/* not CYGWIN or MingW */
 
 #if defined(_DLL)
 #define DLLIMPORT __declspec (dllexport)
@@ -35,7 +35,7 @@
 #define DLLIMPORT __declspec (dllimport)
 #endif
 
-#else							/* not CYGWIN, not MSVC */
+#else							/* not CYGWIN, not MSVC, not MingW */
 
 #define DLLIMPORT
 #endif
-- 
GitLab