⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysv_shmem.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
		return true;			/* if can't stat, be conservative */	hdr = (PGShmemHeader *) shmat(shmId, NULL, PG_SHMAT_FLAGS);	if (hdr == (PGShmemHeader *) -1)		return true;			/* if can't attach, be conservative */	if (hdr->magic != PGShmemMagic ||		hdr->device != statbuf.st_dev ||		hdr->inode != statbuf.st_ino)	{		/*		 * It's either not a Postgres segment, or not one for my data		 * directory.  In either case it poses no threat.		 */		shmdt((void *) hdr);		return false;	}	/* Trouble --- looks a lot like there's still live backends */	shmdt((void *) hdr);#endif	return true;}/* * PGSharedMemoryCreate * * Create a shared memory segment of the given size and initialize its * standard header.  Also, register an on_shmem_exit callback to release * the storage. * * Dead Postgres segments are recycled if found, but we do not fail upon * collision with non-Postgres shmem segments.	The idea here is to detect and * re-use keys that may have been assigned by a crashed postmaster or backend. * * makePrivate means to always create a new segment, rather than attach to * or recycle any existing segment. * * The port number is passed for possible use as a key (for SysV, we use * it to generate the starting shmem key).	In a standalone backend, * zero will be passed. */PGShmemHeader *PGSharedMemoryCreate(Size size, bool makePrivate, int port){	IpcMemoryKey NextShmemSegID;	void	   *memAddress;	PGShmemHeader *hdr;	IpcMemoryId shmid;#ifndef WIN32	struct stat statbuf;#endif	/* Room for a header? */	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));	/* Make sure PGSharedMemoryAttach doesn't fail without need */	UsedShmemSegAddr = NULL;	/* Loop till we find a free IPC key */	NextShmemSegID = port * 1000;	for (NextShmemSegID++;; NextShmemSegID++)	{		/* Try to create new segment */		memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);		if (memAddress)			break;				/* successful create and attach */		/* Check shared memory and possibly remove and recreate */		if (makePrivate)		/* a standalone backend shouldn't do this */			continue;		if ((memAddress = PGSharedMemoryAttach(NextShmemSegID, &shmid)) == NULL)			continue;			/* can't attach, not one of mine */		/*		 * If I am not the creator and it belongs to an extant process,		 * continue.		 */		hdr = (PGShmemHeader *) memAddress;		if (hdr->creatorPID != getpid())		{			if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH)			{				shmdt(memAddress);				continue;		/* segment belongs to a live process */			}		}		/*		 * The segment appears to be from a dead Postgres process, or from a		 * previous cycle of life in this same process.  Zap it, if possible.		 * This probably shouldn't fail, but if it does, assume the segment		 * belongs to someone else after all, and continue quietly.		 */		shmdt(memAddress);		if (shmctl(shmid, IPC_RMID, NULL) < 0)			continue;		/*		 * Now try again to create the segment.		 */		memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);		if (memAddress)			break;				/* successful create and attach */		/*		 * Can only get here if some other process managed to create the same		 * shmem key before we did.  Let him have that one, loop around to try		 * next key.		 */	}	/*	 * OK, we created a new segment.  Mark it as created by this process. The	 * order of assignments here is critical so that another Postgres process	 * can't see the header as valid but belonging to an invalid PID!	 */	hdr = (PGShmemHeader *) memAddress;	hdr->creatorPID = getpid();	hdr->magic = PGShmemMagic;#ifndef WIN32	/* Fill in the data directory ID info, too */	if (stat(DataDir, &statbuf) < 0)		ereport(FATAL,				(errcode_for_file_access(),				 errmsg("could not stat data directory \"%s\": %m",						DataDir)));	hdr->device = statbuf.st_dev;	hdr->inode = statbuf.st_ino;#endif	/*	 * Initialize space allocation status for segment.	 */	hdr->totalsize = size;	hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));	/* Save info for possible future use */	UsedShmemSegAddr = memAddress;	UsedShmemSegID = (unsigned long) NextShmemSegID;	return hdr;}#ifdef EXEC_BACKEND/* * PGSharedMemoryReAttach * * Re-attach to an already existing shared memory segment.	In the non * EXEC_BACKEND case this is not used, because postmaster children inherit * the shared memory segment attachment via fork(). * * UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this * routine.  The caller must have already restored them to the postmaster's * values. */voidPGSharedMemoryReAttach(void){	IpcMemoryId shmid;	void	   *hdr;	void	   *origUsedShmemSegAddr = UsedShmemSegAddr;	Assert(UsedShmemSegAddr != NULL);	Assert(IsUnderPostmaster);#ifdef __CYGWIN__	/* cygipc (currently) appears to not detach on exec. */	PGSharedMemoryDetach();	UsedShmemSegAddr = origUsedShmemSegAddr;#endif	elog(DEBUG3, "Attaching to %p", UsedShmemSegAddr);	hdr = (void *) PGSharedMemoryAttach((IpcMemoryKey) UsedShmemSegID, &shmid);	if (hdr == NULL)		elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %m",			 (int) UsedShmemSegID, UsedShmemSegAddr);	if (hdr != origUsedShmemSegAddr)		elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",			 hdr, origUsedShmemSegAddr);	UsedShmemSegAddr = hdr;		/* probably redundant */}#endif   /* EXEC_BACKEND *//* * PGSharedMemoryDetach * * Detach from the shared memory segment, if still attached.  This is not * intended for use by the process that originally created the segment * (it will have an on_shmem_exit callback registered to do that).	Rather, * this is for subprocesses that have inherited an attachment and want to * get rid of it. */voidPGSharedMemoryDetach(void){	if (UsedShmemSegAddr != NULL)	{		if ((shmdt(UsedShmemSegAddr) < 0)#if defined(EXEC_BACKEND) && defined(__CYGWIN__)		/* Work-around for cygipc exec bug */			&& shmdt(NULL) < 0#endif			)			elog(LOG, "shmdt(%p) failed: %m", UsedShmemSegAddr);		UsedShmemSegAddr = NULL;	}}/* * Attach to shared memory and make sure it has a Postgres header * * Returns attach address if OK, else NULL */static PGShmemHeader *PGSharedMemoryAttach(IpcMemoryKey key, IpcMemoryId *shmid){	PGShmemHeader *hdr;	if ((*shmid = shmget(key, sizeof(PGShmemHeader), 0)) < 0)		return NULL;	hdr = (PGShmemHeader *) shmat(*shmid, UsedShmemSegAddr, PG_SHMAT_FLAGS);	if (hdr == (PGShmemHeader *) -1)		return NULL;			/* failed: must be some other app's */	if (hdr->magic != PGShmemMagic)	{		shmdt((void *) hdr);		return NULL;			/* segment belongs to a non-Postgres app */	}	return hdr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -