mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	[all] Removed call to getppid in SendPostmasterSignal, replacing with a
PostmasterPid variable, which gets set (early) in PostmasterMain
getppid would not be the postmaster?
[fork/exec] Implements processCancelRequest by keeping an array of
pid/cancel_key structs in shared mem
[fork/exec] Moves AttachSharedMemoryAndSemaphores call for backends into
SubPostmasterMain
[win32] Implements reaper/waitpid by keeping an arrays of children
pids,handles in postmaster local mem
      - this item is largely untested, for reasons which should be
obvious, but appears sound
[win32/all] Added extern for pgpipe in Win32 case, and changed the second
pipe call (which seems to have been missed earlier) to pgpipe
[win32] #define'd ftruncate to chsize in the Win32 case
[win32] PG_USLEEP for Win32 has a misplaced paren. Fixed.
[win32] DLLIMPORT handling for MingW case
Claudio Natoli
			
			
This commit is contained in:
		
							parent
							
								
									ede3b762a3
								
							
						
					
					
						commit
						eec08b95e7
					
				| @ -13,7 +13,7 @@ | |||||||
|  * |  * | ||||||
|  *	Copyright (c) 2001-2003, PostgreSQL Global Development Group |  *	Copyright (c) 2001-2003, PostgreSQL Global Development Group | ||||||
|  * |  * | ||||||
|  *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.55 2004/01/26 22:54:56 momjian Exp $ |  *	$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.56 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * ---------- |  * ---------- | ||||||
|  */ |  */ | ||||||
| #include "postgres.h" | #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 piperead(a,b,c)		read(a,b,c) | ||||||
| #define pipewrite(a,b,c)	write(a,b,c) | #define pipewrite(a,b,c)	write(a,b,c) | ||||||
| #else | #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 piperead(a,b,c)		recv(a,b,c,0) | ||||||
| #define pipewrite(a,b,c)	send(a,b,c,0) | #define pipewrite(a,b,c)	send(a,b,c,0) | ||||||
| #endif | #endif | ||||||
| @ -322,7 +322,7 @@ pgstat_init(void) | |||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Create the pipe that controls the statistics collector shutdown | 	 * Create the pipe that controls the statistics collector shutdown | ||||||
| 	 */ | 	 */ | ||||||
| 	if (pipe(pgStatPmPipe) < 0) | 	if (pgpipe(pgStatPmPipe) < 0) | ||||||
| 	{ | 	{ | ||||||
| 		ereport(LOG, | 		ereport(LOG, | ||||||
| 				(errcode_for_socket_access(), | 				(errcode_for_socket_access(), | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.361 2004/01/26 22:54:56 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.362 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  * |  * | ||||||
| @ -141,6 +141,11 @@ typedef struct bkend | |||||||
| 
 | 
 | ||||||
| static Dllist *BackendList; | 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 */ | /* The socket number we are listening for connections on */ | ||||||
| int			PostPortNumber; | int			PostPortNumber; | ||||||
| char	   *UnixSocketDir; | char	   *UnixSocketDir; | ||||||
| @ -299,6 +304,14 @@ __attribute__((format(printf, 1, 2))); | |||||||
| #ifdef EXEC_BACKEND | #ifdef EXEC_BACKEND | ||||||
| #ifdef WIN32 | #ifdef WIN32 | ||||||
| pid_t win32_forkexec(const char* path, char *argv[]); | 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 | #endif | ||||||
| 
 | 
 | ||||||
| static pid_t Backend_forkexec(Port *port); | static pid_t Backend_forkexec(Port *port); | ||||||
| @ -306,6 +319,11 @@ static pid_t Backend_forkexec(Port *port); | |||||||
| static unsigned long tmpBackendFileNum = 0; | static unsigned long tmpBackendFileNum = 0; | ||||||
| void read_backend_variables(unsigned long id, Port *port); | void read_backend_variables(unsigned long id, Port *port); | ||||||
| static bool write_backend_variables(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 | #endif | ||||||
| 
 | 
 | ||||||
| #define StartupDataBase()		SSDataBase(BS_XLOG_STARTUP) | #define StartupDataBase()		SSDataBase(BS_XLOG_STARTUP) | ||||||
| @ -430,7 +448,7 @@ PostmasterMain(int argc, char *argv[]) | |||||||
| 	 */ | 	 */ | ||||||
| 	umask((mode_t) 0077); | 	umask((mode_t) 0077); | ||||||
| 
 | 
 | ||||||
| 	MyProcPid = getpid(); | 	MyProcPid = PostmasterPid = getpid(); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Fire up essential subsystems: memory management | 	 * Fire up essential subsystems: memory management | ||||||
| @ -825,6 +843,21 @@ PostmasterMain(int argc, char *argv[]) | |||||||
| 	 */ | 	 */ | ||||||
| 	BackendList = DLNewList(); | 	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 | 	 * Record postmaster options.  We delay this till now to avoid | ||||||
| 	 * recording bogus options (eg, NBuffers too high for available | 	 * recording bogus options (eg, NBuffers too high for available | ||||||
| @ -1257,11 +1290,7 @@ ProcessStartupPacket(Port *port, bool SSLdone) | |||||||
| 
 | 
 | ||||||
| 	if (proto == CANCEL_REQUEST_CODE) | 	if (proto == CANCEL_REQUEST_CODE) | ||||||
| 	{ | 	{ | ||||||
| #ifdef EXEC_BACKEND |  | ||||||
| 		abort(); /* FIXME: [fork/exec] Whoops. Not handled... yet */ |  | ||||||
| #else |  | ||||||
| 		processCancelRequest(port, buf); | 		processCancelRequest(port, buf); | ||||||
| #endif |  | ||||||
| 		return 127;				/* XXX */ | 		return 127;				/* XXX */ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -1494,8 +1523,12 @@ processCancelRequest(Port *port, void *pkt) | |||||||
| 	CancelRequestPacket *canc = (CancelRequestPacket *) pkt; | 	CancelRequestPacket *canc = (CancelRequestPacket *) pkt; | ||||||
| 	int			backendPID; | 	int			backendPID; | ||||||
| 	long		cancelAuthCode; | 	long		cancelAuthCode; | ||||||
| 	Dlelem	   *curr; |  | ||||||
| 	Backend    *bp; | 	Backend    *bp; | ||||||
|  | #ifndef EXEC_BACKEND | ||||||
|  | 	Dlelem	   *curr; | ||||||
|  | #else | ||||||
|  | 	int i; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	backendPID = (int) ntohl(canc->backendPID); | 	backendPID = (int) ntohl(canc->backendPID); | ||||||
| 	cancelAuthCode = (long) ntohl(canc->cancelAuthCode); | 	cancelAuthCode = (long) ntohl(canc->cancelAuthCode); | ||||||
| @ -1514,16 +1547,17 @@ processCancelRequest(Port *port, void *pkt) | |||||||
| 								 backendPID))); | 								 backendPID))); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| #ifdef EXEC_BACKEND |  | ||||||
| 	else |  | ||||||
| 		AttachSharedMemoryAndSemaphores(); |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	/* See if we have a matching backend */ | 	/* See if we have a matching backend */ | ||||||
| 
 | #ifndef EXEC_BACKEND | ||||||
| 	for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr)) | 	for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr)) | ||||||
| 	{ | 	{ | ||||||
| 		bp = (Backend *) DLE_VAL(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->pid == backendPID) | ||||||
| 		{ | 		{ | ||||||
| 			if (bp->cancel_key == cancelAuthCode) | 			if (bp->cancel_key == cancelAuthCode) | ||||||
| @ -1846,14 +1880,12 @@ reaper(SIGNAL_ARGS) | |||||||
| { | { | ||||||
| 	int			save_errno = errno; | 	int			save_errno = errno; | ||||||
| 
 | 
 | ||||||
| #ifdef WIN32 |  | ||||||
| #warning fix waidpid for Win32 |  | ||||||
| #else |  | ||||||
| #ifdef HAVE_WAITPID | #ifdef HAVE_WAITPID | ||||||
| 	int			status;			/* backend exit status */ | 	int			status;			/* backend exit status */ | ||||||
| 
 |  | ||||||
| #else | #else | ||||||
|  | #ifndef WIN32 | ||||||
| 	union wait	status;			/* backend exit status */ | 	union wait	status;			/* backend exit status */ | ||||||
|  | #endif | ||||||
| #endif | #endif | ||||||
| 	int			exitstatus; | 	int			exitstatus; | ||||||
| 	int			pid;			/* process id of dead backend */ | 	int			pid;			/* process id of dead backend */ | ||||||
| @ -1867,9 +1899,21 @@ reaper(SIGNAL_ARGS) | |||||||
| 	{ | 	{ | ||||||
| 		exitstatus = status; | 		exitstatus = status; | ||||||
| #else | #else | ||||||
|  | #ifndef WIN32 | ||||||
| 	while ((pid = wait3(&status, WNOHANG, NULL)) > 0) | 	while ((pid = wait3(&status, WNOHANG, NULL)) > 0) | ||||||
| 	{ | 	{ | ||||||
| 		exitstatus = status.w_status; | 		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 | #endif | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| @ -1957,7 +2001,6 @@ reaper(SIGNAL_ARGS) | |||||||
| 		CleanupProc(pid, exitstatus); | 		CleanupProc(pid, exitstatus); | ||||||
| 
 | 
 | ||||||
| 	}							/* loop over pending child-death reports */ | 	}							/* loop over pending child-death reports */ | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	if (FatalError) | 	if (FatalError) | ||||||
| 	{ | 	{ | ||||||
| @ -2022,6 +2065,9 @@ CleanupProc(int pid, | |||||||
| 			bp = (Backend *) DLE_VAL(curr); | 			bp = (Backend *) DLE_VAL(curr); | ||||||
| 			if (bp->pid == pid) | 			if (bp->pid == pid) | ||||||
| 			{ | 			{ | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 				ShmemBackendArrayRemove(bp->pid); | ||||||
|  | #endif | ||||||
| 				DLRemove(curr); | 				DLRemove(curr); | ||||||
| 				free(bp); | 				free(bp); | ||||||
| 				DLFreeElem(curr); | 				DLFreeElem(curr); | ||||||
| @ -2092,6 +2138,9 @@ CleanupProc(int pid, | |||||||
| 			/*
 | 			/*
 | ||||||
| 			 * Found entry for freshly-dead backend, so remove it. | 			 * Found entry for freshly-dead backend, so remove it. | ||||||
| 			 */ | 			 */ | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 			ShmemBackendArrayRemove(bp->pid); | ||||||
|  | #endif | ||||||
| 			DLRemove(curr); | 			DLRemove(curr); | ||||||
| 			free(bp); | 			free(bp); | ||||||
| 			DLFreeElem(curr); | 			DLFreeElem(curr); | ||||||
| @ -2296,6 +2345,9 @@ BackendStartup(Port *port) | |||||||
| 	 */ | 	 */ | ||||||
| 	bn->pid = pid; | 	bn->pid = pid; | ||||||
| 	bn->cancel_key = MyCancelKey; | 	bn->cancel_key = MyCancelKey; | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 	ShmemBackendArrayAdd(bn); | ||||||
|  | #endif | ||||||
| 	DLAddHead(BackendList, DLNewElem(bn)); | 	DLAddHead(BackendList, DLNewElem(bn)); | ||||||
| 
 | 
 | ||||||
| 	return STATUS_OK; | 	return STATUS_OK; | ||||||
| @ -2642,6 +2694,9 @@ SubPostmasterMain(int argc, char* argv[]) | |||||||
| 	memset((void*)&port, 0, sizeof(Port)); | 	memset((void*)&port, 0, sizeof(Port)); | ||||||
| 	Assert(argc == 2); | 	Assert(argc == 2); | ||||||
| 
 | 
 | ||||||
|  | 	/* Do this sooner rather than later... */ | ||||||
|  | 	IsUnderPostmaster = true;	/* we are a postmaster subprocess now */ | ||||||
|  | 
 | ||||||
| 	/* Setup global context */ | 	/* Setup global context */ | ||||||
| 	MemoryContextInit(); | 	MemoryContextInit(); | ||||||
| 	InitializeGUCOptions(); | 	InitializeGUCOptions(); | ||||||
| @ -2661,6 +2716,9 @@ SubPostmasterMain(int argc, char* argv[]) | |||||||
| 	load_user(); | 	load_user(); | ||||||
| 	load_group(); | 	load_group(); | ||||||
| 
 | 
 | ||||||
|  | 	/* Attach process to shared segments */ | ||||||
|  | 	AttachSharedMemoryAndSemaphores(); | ||||||
|  | 
 | ||||||
| 	/* Run backend */ | 	/* Run backend */ | ||||||
| 	proc_exit(BackendRun(&port)); | 	proc_exit(BackendRun(&port)); | ||||||
| } | } | ||||||
| @ -3129,6 +3187,9 @@ SSDataBase(int xlop) | |||||||
| 
 | 
 | ||||||
| 		bn->pid = pid; | 		bn->pid = pid; | ||||||
| 		bn->cancel_key = PostmasterRandom(); | 		bn->cancel_key = PostmasterRandom(); | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 		ShmemBackendArrayAdd(bn); | ||||||
|  | #endif | ||||||
| 		DLAddHead(BackendList, DLNewElem(bn)); | 		DLAddHead(BackendList, DLNewElem(bn)); | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| @ -3278,6 +3339,7 @@ write_backend_variables(Port *port) | |||||||
| 	write_var(ShmemIndexLock,fp); | 	write_var(ShmemIndexLock,fp); | ||||||
| 	write_var(ShmemVariableCache,fp); | 	write_var(ShmemVariableCache,fp); | ||||||
| 	write_var(ShmemIndexAlloc,fp); | 	write_var(ShmemIndexAlloc,fp); | ||||||
|  | 	write_var(ShmemBackendArray,fp); | ||||||
| 
 | 
 | ||||||
| 	write_var(LWLockArray,fp); | 	write_var(LWLockArray,fp); | ||||||
| 	write_var(ProcStructLock,fp); | 	write_var(ProcStructLock,fp); | ||||||
| @ -3285,6 +3347,7 @@ write_backend_variables(Port *port) | |||||||
| 
 | 
 | ||||||
| 	write_var(PreAuthDelay,fp); | 	write_var(PreAuthDelay,fp); | ||||||
| 	write_var(debug_flag,fp); | 	write_var(debug_flag,fp); | ||||||
|  | 	write_var(PostmasterPid,fp); | ||||||
| 
 | 
 | ||||||
| 	/* Release file */ | 	/* Release file */ | ||||||
| 	if (FreeFile(fp)) | 	if (FreeFile(fp)) | ||||||
| @ -3338,6 +3401,7 @@ read_backend_variables(unsigned long id, Port *port) | |||||||
| 	read_var(ShmemIndexLock,fp); | 	read_var(ShmemIndexLock,fp); | ||||||
| 	read_var(ShmemVariableCache,fp); | 	read_var(ShmemVariableCache,fp); | ||||||
| 	read_var(ShmemIndexAlloc,fp); | 	read_var(ShmemIndexAlloc,fp); | ||||||
|  | 	read_var(ShmemBackendArray,fp); | ||||||
| 
 | 
 | ||||||
| 	read_var(LWLockArray,fp); | 	read_var(LWLockArray,fp); | ||||||
| 	read_var(ProcStructLock,fp); | 	read_var(ProcStructLock,fp); | ||||||
| @ -3345,6 +3409,7 @@ read_backend_variables(unsigned long id, Port *port) | |||||||
| 
 | 
 | ||||||
| 	read_var(PreAuthDelay,fp); | 	read_var(PreAuthDelay,fp); | ||||||
| 	read_var(debug_flag,fp); | 	read_var(debug_flag,fp); | ||||||
|  | 	read_var(PostmasterPid,fp); | ||||||
| 
 | 
 | ||||||
| 	/* Release file */ | 	/* Release file */ | ||||||
| 	FreeFile(fp); | 	FreeFile(fp); | ||||||
| @ -3354,6 +3419,55 @@ read_backend_variables(unsigned long id, Port *port) | |||||||
| 				 errmsg("could not remove file \"%s\": %m", filename))); | 				 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 | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef WIN32 | #ifdef WIN32 | ||||||
| @ -3393,14 +3507,111 @@ pid_t win32_forkexec(const char* path, char *argv[]) | |||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	if (!IsUnderPostmaster) | ||||||
| 	   FIXME: [fork/exec] we might need to keep the following handle/s, | 		/* We are the Postmaster creating a child... */ | ||||||
| 	   depending on how we implement signalling. | 		win32_AddChild(pi.dwProcessId,pi.hProcess); | ||||||
| 	*/ | 	else | ||||||
| 		CloseHandle(pi.hProcess); | 		CloseHandle(pi.hProcess); | ||||||
| 	CloseHandle(pi.hThread); | 	CloseHandle(pi.hThread); | ||||||
| 
 | 
 | ||||||
| 	return pi.dwProcessId; | 	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 | #endif | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.62 2004/01/26 22:54:57 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.63 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -63,6 +63,9 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, | |||||||
| 	size += LWLockShmemSize(); | 	size += LWLockShmemSize(); | ||||||
| 	size += SInvalShmemSize(maxBackends); | 	size += SInvalShmemSize(maxBackends); | ||||||
| 	size += FreeSpaceShmemSize(); | 	size += FreeSpaceShmemSize(); | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 	size += ShmemBackendArraySize(); | ||||||
|  | #endif | ||||||
| #ifdef STABLE_MEMORY_STORAGE | #ifdef STABLE_MEMORY_STORAGE | ||||||
| 	size += MMShmemSize(); | 	size += MMShmemSize(); | ||||||
| #endif | #endif | ||||||
| @ -132,6 +135,13 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, | |||||||
| 	 * Set up child-to-postmaster signaling mechanism | 	 * Set up child-to-postmaster signaling mechanism | ||||||
| 	 */ | 	 */ | ||||||
| 	PMSignalInit(); | 	PMSignalInit(); | ||||||
|  | 
 | ||||||
|  | #ifdef EXEC_BACKEND | ||||||
|  | 	/*
 | ||||||
|  | 	 * Alloc the win32 shared backend array | ||||||
|  | 	 */ | ||||||
|  | 	ShmemBackendArrayAllocation(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.10 2004/01/26 22:54:57 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.11 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  *------------------------------------------------------------------------- |  *------------------------------------------------------------------------- | ||||||
|  */ |  */ | ||||||
| @ -63,8 +63,8 @@ SendPostmasterSignal(PMSignalReason reason) | |||||||
| 		return; | 		return; | ||||||
| 	/* Atomically set the proper flag */ | 	/* Atomically set the proper flag */ | ||||||
| 	PMSignalFlags[reason] = true; | 	PMSignalFlags[reason] = true; | ||||||
| 	/* Send signal to postmaster (assume it is our direct parent) */ | 	/* Send signal to postmaster */ | ||||||
| 	kill(getppid(), SIGUSR1); | 	kill(PostmasterPid, SIGUSR1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.385 2004/01/26 22:54:57 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.386 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  this is the "main" module of the postgres backend and |  *	  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"), | 					 errmsg("invalid command-line arguments for server process"), | ||||||
| 					 errhint("Try \"%s --help\" for more information.", argv[0]))); | 					 errhint("Try \"%s --help\" for more information.", argv[0]))); | ||||||
| 		} | 		} | ||||||
| #ifdef EXEC_BACKEND | 
 | ||||||
| 		AttachSharedMemoryAndSemaphores(); |  | ||||||
| #endif |  | ||||||
| 		XLOGPathInit(); | 		XLOGPathInit(); | ||||||
| 
 | 
 | ||||||
| 		BaseInit(); | 		BaseInit(); | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|  * |  * | ||||||
|  * |  * | ||||||
|  * IDENTIFICATION |  * IDENTIFICATION | ||||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.79 2004/01/26 22:54:57 momjian Exp $ |  *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.80 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  Globals used all over the place should be declared here and not |  *	  Globals used all over the place should be declared here and not | ||||||
| @ -53,6 +53,8 @@ BackendId	MyBackendId; | |||||||
| char	   *DatabasePath = NULL; | char	   *DatabasePath = NULL; | ||||||
| Oid			MyDatabaseId = InvalidOid; | Oid			MyDatabaseId = InvalidOid; | ||||||
| 
 | 
 | ||||||
|  | pid_t PostmasterPid = 0; | ||||||
|  | 
 | ||||||
| /* these are initialized for the bootstrap/standalone case: */ | /* these are initialized for the bootstrap/standalone case: */ | ||||||
| bool		IsPostmasterEnvironment = false; | bool		IsPostmasterEnvironment = false; | ||||||
| bool		IsUnderPostmaster = false; | bool		IsUnderPostmaster = false; | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
|  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group |  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group | ||||||
|  * Portions Copyright (c) 1994, Regents of the University of California |  * Portions Copyright (c) 1994, Regents of the University of California | ||||||
|  * |  * | ||||||
|  * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.147 2004/01/26 22:54:57 momjian Exp $ |  * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.148 2004/01/26 22:59:53 momjian Exp $ | ||||||
|  * |  * | ||||||
|  * NOTES |  * NOTES | ||||||
|  *	  some of the information in this file should be moved to |  *	  some of the information in this file should be moved to | ||||||
| @ -109,10 +109,14 @@ do { \ | |||||||
| #else | #else | ||||||
| #define PG_USLEEP(_usec) \ | #define PG_USLEEP(_usec) \ | ||||||
| do { \ | do { \ | ||||||
| 	Sleep(_usec < 500) ? 1 : (_usec+500)/ 1000); \ | 	Sleep((_usec) < 500 ? 1 : ((_usec)+500)/ 1000); \ | ||||||
| } while(0) | } while(0) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef WIN32 | ||||||
|  | #define ftruncate(a,b)	chsize(a,b) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /*****************************************************************************
 | /*****************************************************************************
 | ||||||
|  *	  globals.h --															 * |  *	  globals.h --															 * | ||||||
|  *****************************************************************************/ |  *****************************************************************************/ | ||||||
| @ -132,6 +136,7 @@ extern void ClosePostmasterPorts(bool pgstat_too); | |||||||
| /*
 | /*
 | ||||||
|  * from utils/init/globals.c |  * from utils/init/globals.c | ||||||
|  */ |  */ | ||||||
|  | extern pid_t PostmasterPid; | ||||||
| extern bool IsPostmasterEnvironment; | extern bool IsPostmasterEnvironment; | ||||||
| extern bool IsUnderPostmaster; | extern bool IsUnderPostmaster; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| /* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.15 2004/01/26 22:54:58 momjian Exp $ */ | /* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.16 2004/01/26 22:59:54 momjian Exp $ */ | ||||||
| 
 | 
 | ||||||
| /* undefine and redefine after #include */ | /* undefine and redefine after #include */ | ||||||
| #undef mkdir | #undef mkdir | ||||||
| @ -15,7 +15,7 @@ | |||||||
| #define NOFILE		  100 | #define NOFILE		  100 | ||||||
| 
 | 
 | ||||||
| /* defines for dynamic linking on Win32 platform */ | /* defines for dynamic linking on Win32 platform */ | ||||||
| #ifdef __CYGWIN__ | #if defined(__CYGWIN__) || defined(__MINGW32__) | ||||||
| 
 | 
 | ||||||
| #if __GNUC__ && ! defined (__declspec) | #if __GNUC__ && ! defined (__declspec) | ||||||
| #error You need egcs 1.1 or newer for compiling! | #error You need egcs 1.1 or newer for compiling! | ||||||
| @ -27,7 +27,7 @@ | |||||||
| #define DLLIMPORT __declspec (dllimport) | #define DLLIMPORT __declspec (dllimport) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #elif defined(WIN32) && defined(_MSC_VER)		/* not CYGWIN */ | #elif defined(WIN32) && defined(_MSC_VER)		/* not CYGWIN or MingW */ | ||||||
| 
 | 
 | ||||||
| #if defined(_DLL) | #if defined(_DLL) | ||||||
| #define DLLIMPORT __declspec (dllexport) | #define DLLIMPORT __declspec (dllexport) | ||||||
| @ -35,7 +35,7 @@ | |||||||
| #define DLLIMPORT __declspec (dllimport) | #define DLLIMPORT __declspec (dllimport) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #else							/* not CYGWIN, not MSVC */ | #else							/* not CYGWIN, not MSVC, not MingW */ | ||||||
| 
 | 
 | ||||||
| #define DLLIMPORT | #define DLLIMPORT | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user