📄 cj_semaphore.c
字号:
/*****************************************************************************/
/* */
/* 文件名:CJ_SEMAPHORE.C */
/* 创建人:王克锋 */
/* 日 期:2005-03-03 */
/* 描 述:文件处理函数组包含文件 */
/* */
/* */
/* 修改人: */
/* 日 期: */
/* 描 述: */
/* */
/*****************************************************************************/
#include "cj_semaphore.h"
static void dec_sem_handle(int);
static void inc_sem_handle(int);
int inc_flag=0;
int dec_flag=0;
#define YCJBG_PUSH_ERROR(lno, str) \
CJEMPush(v_stack, 1, 0, 0, "000", 0, lno, "cj_semaphore.c", str)
#ifdef YCJPLAT_WINDOWS
/*本函数用于获取WINDOWS最近一次的错误信息描述*/
int GetLastErrMsg(char sMsg[], int nMaxLen)
{
LPVOID lpMsg;
int nMsgLen=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL,
GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsg,0,NULL);
if (nMsgLen<=nMaxLen-1) strcpy(sMsg, (char*)lpMsg);
else { strncpy(sMsg, (char*)lpMsg, nMaxLen-1); sMsg[nMaxLen-1]=0; }
LocalFree( lpMsg );
return nMsgLen;
}
#endif
/*****************************************************************************/
/* */
/* 函数名:CJSEInitial */
/* 创建人:王克锋 */
/* 日 期:2005-03-03 */
/* 接 口: 1. PTCJSEStru v_ss 信号灯结构指针 */
/* 2. int v_semid 信号灯对象标识 */
/* 3. int v_cnt 包含的信号灯数量 */
/* 4. PTCJEMStack v_stack 错误堆栈指针 */
/* 返 回:YCJOK:成功;YCJERROR:失败 */
/* 描 述:创建信号灯对象 */
/* */
/* */
/* 修改人: */
/* 日 期: */
/* 描 述: */
/* */
/*****************************************************************************/
int CJSEInitial(PTCJSEStru v_ss, TCJUINT4 v_semid, TCJUINT4 v_cnt,
PTCJEMStack v_stack)
{
int i;
#ifdef YCJPLAT_WINDOWS
char sErrMsg[1024]; HANDLE hSem;
char sem_name[YCJ_MAX_SEM_SIZE+1];
v_ss->hsem=(HANDLE*)malloc(sizeof(HANDLE)*v_cnt);
if (v_ss->hsem==NULL) return YCJERROR;
for (i=0; i<v_cnt; i++)
{
sprintf(sem_name, "CJSEM%d_%d", v_semid, i);
hSem=CreateSemaphore(NULL, 0, LONG_MAX, sem_name);
v_ss->hsem[i]=hSem;
if (v_ss->hsem[i]==NULL)
{
GetLastErrMsg(sErrMsg, 1024);
YCJBG_PUSH_ERROR(50, sErrMsg);
free(v_ss->hsem);
v_ss->hsem=NULL;
return YCJERROR;
}
}
#else
v_ss->hsem = semget(v_semid, v_cnt, IPC_CREAT | IPC_EXCL | 0600);
if (v_ss->hsem==-1)
{
YCJBG_PUSH_ERROR(63, "Semaphore create error");
return YCJERROR;
}
#endif
v_ss->creator=1;
v_ss->cnt=v_cnt;
v_ss->semid=v_semid;
return YCJOK;
}
/*****************************************************************************/
/* */
/* 函数名:CJSEAttach */
/* 创建人:王克锋 */
/* 日 期:2005-03-03 */
/* 接 口:1. PTCJSEStru v_ss 信号灯结构指针 */
/* 2. int v_semid 信号灯对象标识 */
/* 3. int v_cnt 包含的信号灯数量 */
/* 4. PTCJEMStack v_stack 错误堆栈指针 */
/* 返 回:YCJOK:成功;YCJERROR:失败 */
/* 描 述:映射信号灯对象 */
/* */
/* */
/* 修改人: */
/* 日 期: */
/* 描 述: */
/* */
/*****************************************************************************/
int CJSEAttach(PTCJSEStru v_ss, TCJUINT4 v_semid, TCJUINT4 v_cnt,
PTCJEMStack v_stack)
{
#ifdef YCJPLAT_WINDOWS
char sem_name[YCJ_MAX_SEM_SIZE+1];
sprintf(v_ss->semname, "CJSEM%d", v_semid);
for (i=0; i<v_cnt; i++)
{
sprintf(sem_name, "CJSEM%d_%d", v_semid, i);
v_ss->hsem[i]=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,sem_name);
if (v_ss->hsem[i]==NULL)
{
GetLastErrMsg(sErrMsg, 1024);
YCJBG_PUSH_ERROR(132, sErrMsg);
return YCJERROR;
}
}
#else
v_ss->hsem=semget(v_semid,0,0);
if (v_ss->hsem==-1) return YCJERROR;
#endif
v_ss->creator=0;
v_ss->cnt=v_cnt;
v_ss->semid=v_semid;
return YCJOK;
}
/*****************************************************************************/
/* */
/* 函数名:CJSEInc */
/* 创建人:王克锋 */
/* 日 期:2005-03-03 */
/* 接 口:1. PTCJSEStru v_ss 信号灯结构指针 */
/* 2. int v_sno 信号灯序号 */
/* 3. unsigned int v_val 信号灯增加的数值 */
/* 4. PTCJEMStack v_stack 错误堆栈指针 */
/* 返 回:YCJOK:成功;YCJERROR:失败 */
/* 描 述:指定信号灯执行"加" */
/* */
/* */
/* 修改人: */
/* 日 期: */
/* 描 述: */
/* */
/*****************************************************************************/
static void inc_sem_handle(int signo)
{
inc_flag = 1;
}
int CJSEInc(PTCJSEStru v_ss, TCJUINT4 v_sno, TCJUINT4 v_val,
TCJUINT4 v_timeout,PTCJEMStack v_stack)
{
if ( v_val == 0 ) return YCJOK;
#ifdef YCJPLAT_WINDOWS
char sErrMsg[1024]; int i;
for (i=0; i<v_sno; i++)
{
if (ReleaseSemaphore(v_ss->hsem[v_sno], v_val, NULL)==0)
{
GetLastErrMsg(sErrMsg, 1024);
YCJBG_PUSH_ERROR(99, "Semaphore release error");
return YCJERROR;
}
}
#else
signal(SIGALRM, inc_sem_handle);
alarm(v_timeout);
struct sembuf sops;
if (v_ss==NULL || v_sno >= v_ss->cnt) return YCJERROR;
sops.sem_num = v_sno;
sops.sem_op = v_val;
sops.sem_flg = SEM_UNDO;
inc_flag=0;
while( inc_flag==0 )
{
if(inc_flag==1) break; // 信号 SIGALRM 到达
if ( semop(v_ss->hsem,&sops,1)==-1 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -