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

📄 sema.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
字号:
/*------------------------------------------------------------------------- * * sema.c *	  Microsoft Windows Win32 Semaphores Emulation * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/port/win32/sema.c,v 1.11 2005/10/15 02:49:23 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "storage/shmem.h"#include <errno.h>typedef struct{	int			m_numSems;	off_t		m_semaphoreHandles;	/* offset from beginning of header */	off_t		m_semaphoreCounts;	/* offset from beginning of header */}	win32_sem_set_hdr;/* Control of a semaphore pool. The pool is an area in which we stored all** the semIds of the pool. The first long is the number of semaphore** allocated in the pool followed by semaphore handles*/intsemctl(int semId, int semNum, int flag, union semun semun){	win32_sem_set_hdr *the_set = (win32_sem_set_hdr *) MAKE_PTR(semId);	/* semNum might be 0 */	/* semun.array contains the sem initial values */	int		   *sem_counts = (int *) ((off_t) the_set + the_set->m_semaphoreCounts);	/* Fix the count of all sem of the pool to semun.array */	if (flag == SETALL)	{		int			i;		struct sembuf sops;		sops.sem_flg = IPC_NOWAIT;		for (i = 0; i < the_set->m_numSems; ++i)		{			if (semun.array[i] == sem_counts[i])				continue;		/* Nothing to do */			if (semun.array[i] < sem_counts[i])				sops.sem_op = -1;			else				sops.sem_op = 1;			sops.sem_num = i;			/* Quickly lock/unlock the semaphore (if we can) */			if (semop(semId, &sops, 1) < 0)				return -1;		}		return 1;	}	/* Fix the count of one semaphore to semun.val */	else if (flag == SETVAL)	{		if (semun.val != sem_counts[semNum])		{			struct sembuf sops;			sops.sem_flg = IPC_NOWAIT;			sops.sem_num = semNum;			if (semun.val < sem_counts[semNum])				sops.sem_op = -1;			else				sops.sem_op = 1;			/* Quickly lock/unlock the semaphore (if we can) */			if (semop(semId, &sops, 1) < 0)				return -1;		}		return 1;	}	/* Delete the pool */	else if (flag == IPC_RMID)	{		int			i;		HANDLE	   *sem_handles = (HANDLE *) ((off_t) the_set + the_set->m_semaphoreHandles);		/* Loop over all semaphore to delete them */		for (i = 0; i < the_set->m_numSems; ++i)			CloseHandle(sem_handles[i]);		return 1;	}	/* Get the current semaphore count */	else if (flag == GETNCNT)		return the_set->m_numSems;	/* Get the current semaphore count of the first semaphore in the pool */	else if (flag == GETVAL)		return sem_counts[semNum];	/* Other commands not yet supported */	else	{		errno = EINVAL;		return -1;	}}/* Find a pool id based on IPC key */intsemget(int semKey, int semNum, int flags){	char		semname[32];	char		cur_num[20];	DWORD		last_error;	char	   *num_part;	bool		ans = true;	SECURITY_ATTRIBUTES sec_attrs;	HANDLE		cur_handle;	bool		found = false;	Size		sem_set_size = sizeof(win32_sem_set_hdr) + semNum * (sizeof(HANDLE) + sizeof(int));	HANDLE	   *sem_handles = NULL;	int		   *sem_counts = NULL;	int			i;	sec_attrs.nLength = sizeof(sec_attrs);	sec_attrs.lpSecurityDescriptor = NULL;	sec_attrs.bInheritHandle = TRUE;	sprintf(semname, "PG_SEMSET.%d.", semKey);	num_part = semname + strlen(semname);	strcpy(num_part, _itoa(_getpid() * -1, cur_num, 10));		/* For shared memory,																 * include the pid */	win32_sem_set_hdr *new_set = (win32_sem_set_hdr *) ShmemInitStruct(semname, sem_set_size, &found);	if (found)	{		/* This should *never* happen */		errno = EEXIST;		return -1;	}	new_set->m_numSems = semNum;	new_set->m_semaphoreHandles = sizeof(win32_sem_set_hdr);	/* array starts after header */	new_set->m_semaphoreCounts = new_set->m_semaphoreHandles + (sizeof(HANDLE) * semNum);	sem_handles = (HANDLE *) ((off_t) new_set + new_set->m_semaphoreHandles);	sem_counts = (int *) ((off_t) new_set + new_set->m_semaphoreCounts);	for (i = 0; i < semNum && ans; ++i)	{		strcpy(num_part, _itoa(i, cur_num, 10));		if (flags & IPC_CREAT)			cur_handle = CreateSemaphore(&sec_attrs, 0, 1, semname);		else			cur_handle = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, semname);		sem_handles[i] = cur_handle;		last_error = GetLastError();		if (!cur_handle)		{			errno = EACCES;			ans = false;		}		else if (last_error == ERROR_ALREADY_EXISTS && (flags & (IPC_CREAT | IPC_EXCL)))		{			errno = EEXIST;			ans = false;		}	}	if (ans)		return MAKE_OFFSET(new_set);	else	{		int			i;		/* Blow away what we've got right now... */		for (i = 0; i < semNum; ++i)		{			if (sem_handles[i])				CloseHandle(sem_handles[i]);			else				break;		}		return -1;	}}/* Acquire or release in the semaphore pool */intsemop(int semId, struct sembuf * sops, int nsops){	win32_sem_set_hdr *the_set = (win32_sem_set_hdr *) MAKE_PTR(semId);	HANDLE	   *sem_handles = (HANDLE *) ((off_t) the_set + the_set->m_semaphoreHandles);	int		   *sem_counts = (int *) ((off_t) the_set + the_set->m_semaphoreCounts);	HANDLE		cur_handle;	if (nsops != 1)	{		/*		 * Not supported (we return on 1st success, and don't cancel earlier		 * ops)		 */		errno = E2BIG;		return -1;	}	cur_handle = sem_handles[sops[0].sem_num];	if (sops[0].sem_op == -1)	{		DWORD		ret;		HANDLE		wh[2];		wh[0] = cur_handle;		wh[1] = pgwin32_signal_event;		ret = WaitForMultipleObjectsEx(2, wh, FALSE, (sops[0].sem_flg & IPC_NOWAIT) ? 0 : INFINITE, TRUE);		if (ret == WAIT_OBJECT_0)		{			/* We got it! */			sem_counts[sops[0].sem_num]--;			return 0;		}		else if (ret == WAIT_OBJECT_0 + 1 || ret == WAIT_IO_COMPLETION)		{			/* Signal event is set - we have a signal to deliver */			pgwin32_dispatch_queued_signals();			errno = EINTR;		}		else if (ret == WAIT_TIMEOUT)			/* Couldn't get it */			errno = EAGAIN;		else			errno = EIDRM;	}	else if (sops[0].sem_op > 0)	{		/* Don't want the lock anymore */		sem_counts[sops[0].sem_num]++;		ReleaseSemaphore(cur_handle, sops[0].sem_op, NULL);		return 0;	}	else		/* Not supported */		errno = ERANGE;	/* If we get down here, then something is wrong */	return -1;}

⌨️ 快捷键说明

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