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

📄 slmesg.c

📁 UNIX/LINUX下自编的消息队列程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	j = 0;
	if(msgrcv(pms.msgid, &mbuf, 0, getpid(), 0)<0 || tmout) j = -2;
	SLMesgLock(msgptr, No);
	
	oldp=&mh->FirstProc;
	wpqclr=start;
	while(1)
	{
		if(*oldp < 1) break;
		if(*oldp == i + 1) {
			*oldp = wpq->next;
			break;
		}
		wpqclr=start + *oldp - 1;
		oldp=&wpqclr->next;
	}
	memset((char *)wpq, '\0', sizeof(WaitProcQue));
	if(timeout) alarm(0);
	return j;
}

MsgRec *
SearchMsg(MsgRec *mrec,char *msgptr)
{
	MsgHead     *mh;
	MsgRec      *msgrec,*mr;
	int     i;

	mh=(MsgHead *)msgptr;

	msgrec=(MsgRec *)(msgptr + mh->RecStart);

	if(mh->MsgNum < 1) return NULL;
	for(i=0;i<mh->MsgNum;i++) {
		mr=msgrec + i;
		if(!MsgCompMsg(mrec,mr)) return mr;
	}

	return NULL;
}

/*发送消息,发送一条消息到消息队列中 */
int SLMesgSnd(int No,char *buf,int flag)
{
	int     len,i,j,ob,timeout=flag & TIMEOUTMASK;
	char        *ptr,*msgptr,*ptr1;
	MsgHead     *mh;
	MsgRec      *mr,*mr1;
	MesgStru    *mst;
	int         ret=0;

	if(No<1 || buf==NULL) return -1;
	if(pmsptr==NULL) return -2;
	for(i=0;i<MaxMsgNum;i++)
		if(pms.MsgNo[i]==No) break;
	if(i>=MaxMsgNum) return -2;
	if(pms.MsgBuf[i]==NULL) {
		pms.MsgNo[i]=-1;
		return -2;
	}

	mst=(MesgStru *)buf;

	if(mst->m_sour < 0 || mst->m_dest < 0 || mst->m_msgtype < 0 
		|| mst->m_msgid < 0 || mst->m_msglen < 1) {
		return -4;
	}
	signal(SIGALRM,SIG_IGN);

	msgptr=pms.MsgBuf[i];
	SLMesgLock(msgptr, No);

//	MsgQueChk(msgptr);
	if (strncmp(&msgptr[1],SLMQVER,7)) {
		SLMesgUnLock(msgptr);
		return -3;
		}
	mh=(MsgHead *)msgptr;
	
	ob=(mst->m_msglen + mh->BlockSize -1)/mh->BlockSize;
	mr=(MsgRec *)buf;

	if (flag & M_NOWAIT)
	{
		if (mh->UnuseBlocks<ob)
		{
			SLMesgUnLock(msgptr);
			return -5;
		}
	}

	while(mh->UnuseBlocks < ob) {
		if(ProcWait(No, msgptr, mr, ~M_RCVPROC, timeout) < 0) {
			SLMesgUnLock(msgptr);
			return -6;
		}
	}

	mr=(MsgRec *)(msgptr + mh->RecStart);
	mr +=mh->MsgNum;
	memcpy(mr,(MsgRec *)buf,sizeof(MesgStru));
	if((mr->Start=TabTest(msgptr))<1)
	{
		SLMesgUnLock(msgptr);
		memset((char *)mr, '\0', sizeof(MsgRec));
		return -7;
	}
	time(&mr->m_wrtm);
	//置入写入时间
	ptr1=buf + sizeof(MesgStru);
	ptr=msgptr + mh->DataStart + (mr->Start-1) * mh->BlockSize;
	len=mr->m_msglen;
	i=mh->BlockSize;

	TabSet(msgptr,mr->Start,-1);
	ob=mr->Start;
	mh->UnuseBlocks--;
	for(;;)
	{
		j=len>i?i:len;
		memcpy(ptr,ptr1,j);
		len-=j;
		ptr+=j;
		ptr1+=j;
		if(!len)
		{
			mh->MsgNum++;
			MsgNotice(msgptr,0,mr);
			SLMesgUnLock(msgptr);
//			mh->sndnum++;
//			if(mh->sndnum % 10000 == 0) printf("sndnum = %d\n", mh->sndnum);
			return 0;
		}
		if((j=TabTest(msgptr))<0)
		{
			SLMesgUnLock(msgptr);
			return -8;
		}
		ptr=msgptr+ mh->DataStart + (j-1) * mh->BlockSize;
		TabSet(msgptr,ob,j);
		TabSet(msgptr,j,-1);
		mh->UnuseBlocks--;
		ob=j;
		i=mh->BlockSize;
	}
}

/* 接收消息,从消息队列中接收一条消息 */
int SLMesgRcv(int No,char *buf,int flag)
{
	int     len,i,j,ob,cb,timeout = flag & TIMEOUTMASK;
	char        *ptr,*ptr1,*msgptr;
	long        wrtm;
	MsgHead     *mh;
	MsgRec      *mr,*mr1,*mrec;
	MesgStru    *mst;

	if(No<1 || buf == NULL) return -1;
	if(pmsptr==NULL) return -2;
	for(i=0;i<MaxMsgNum;i++)
		if(pms.MsgNo[i]==No) break;
	if(i>=MaxMsgNum) return -2;
	if(pms.MsgBuf[i]==NULL)
	{
		pms.MsgNo[i]=-1;
		return -2;
	}
	mst=(MesgStru *)buf;
	if(mst->m_msglen < 1) {
		return -4;
	}
	signal(SIGALRM,SIG_IGN);
	msgptr=pms.MsgBuf[i];
	SLMesgLock(msgptr, No);

	if (strncmp(&msgptr[1], SLMQVER,7))
	{
		SLMesgUnLock(msgptr);
		return -3;
	}
	mr1=(MsgRec *)buf;
	mh=(MsgHead *)msgptr;
	

	if(flag & M_NOWAIT)
		if(mh->MsgNum<1)
		{
			SLMesgUnLock(msgptr);
			return -5;
		}

	while((mr=SearchMsg(mr1,msgptr))==NULL)
	{
		if(ProcWait(No, msgptr, mr1, M_RCVPROC, timeout) < 0) {
			SLMesgUnLock(msgptr);
			return -6;
		}
	}

	ptr1=buf + sizeof(MesgStru);
	ptr=msgptr+ mh->DataStart + (mr->Start-1) * mh->BlockSize;
	cb=mr->Start;
	ob=TabRead(msgptr,cb);

	if(!(flag & M_INQ)) {
		TabSet(msgptr,mr->Start,0);
		mh->UnuseBlocks++;
		}

	len=mr->m_msglen > mr1->m_msglen ? mr1->m_msglen : mr->m_msglen;

	i=mh->BlockSize;
	for(;;)
	{
		j=len>i?i:len;
		memcpy(ptr1,ptr,j);
		memset(ptr,'\0',j);
		len-=j;
		ptr1+=j;
		ptr+=j;

		if(len<1 || ob<1 )
		{
			mh->MsgNum--;
			time(&wrtm);
			len=mr->m_msglen > mr1->m_msglen ? mr1->m_msglen : mr->m_msglen;
			memcpy(mr1, mr, sizeof(MesgStru));
			mst->m_overtime=wrtm - mr->m_wrtm;
			mr1->m_msglen = len;

			if(!(flag & M_INQ))
				while(ob>0) {
					cb=TabRead(msgptr, ob);
					TabSet(msgptr, ob, 0);
					mh->UnuseBlocks++;
					ob=cb;
				}
			if(!(flag & M_INQ)) {
				mrec=(MsgRec *)(msgptr + mh->RecStart);
				i=mh->MsgNum - (mr-mrec);
				if(i>0)
					memcpy((char *)mr,(char *)(mr+1),i * sizeof(MsgRec));
			}
			MsgNotice(msgptr,1,mr1);
			SLMesgUnLock(msgptr);
//			mh->rcvnum++;
//			if(mh->rcvnum % 10000 == 0) printf("rcvnum = %d\n", mh->rcvnum);
			return 0;
		}

		ptr=msgptr+mh->DataStart + (ob - 1)*mh->BlockSize;
		cb=ob;

		ob=TabRead(msgptr,cb);
		if(!(flag & M_INQ)) {
			TabSet(msgptr,cb,0);
			mh->UnuseBlocks++;
			}
		i=mh->BlockSize;
	}
}


/* 检查消息队列,本函数完成以下功能:
  1.检查等待进程队列,如在等待进程队列中有已不存在的进程,则清理结点,
  2.检查消息头,若有超时消息,则做如下处理:
  	首先看flag,flag的低六位为超时时间,高两位可有如下值:
  	    M_INQ : 如果flag & M_INQ 为真,则读出超时消息,原消息保持不变,否则读出原消息,原消息删除
  	在读出原消息时,若buf为空指针,则不读出,按flag指示操作
  	作此类操作时,若buf为空,则不读出消息,但若buf不为空时,
  	则buf的消息头中除m_msglen指示消息缓冲区长度外,其它均无意义
  	返回说明:
  	<0 运行有误,
  	=0 正常,已读出一条超时消息
  	>0 无超时消息
  	*/
int SLMesgClr(int No,char *buf,int flag)
{
	int     len,i,j,ob,cb,timeout = flag & TIMEOUTMASK, *mac;
	char        *ptr,*ptr1,*msgptr;
	long        wrtm;
	MsgHead     *mh;
	MsgRec      *mr,*mr1,*mrec;
	MesgStru    *mst;
	WaitProcQue	*wpq, *start;


	if(No<1) return -1;
	if(pmsptr==NULL) return -2;
	for(i=0;i<MaxMsgNum;i++)
		if(pms.MsgNo[i]==No) break;
	if(i>=MaxMsgNum) return -2;
	if(pms.MsgBuf[i]==NULL)
	{
		pms.MsgNo[i]=-1;
		return -2;
	}
	
	if(buf) {
		mst=(MesgStru *)buf;
		if(mst->m_msglen < 1)
			return -4;
	}
	signal(SIGALRM,SIG_IGN);
	msgptr=pms.MsgBuf[i];
	SLMesgLock(msgptr, No);

	if (strncmp(&msgptr[1], SLMQVER,7))
	{
		SLMesgUnLock(msgptr);
		return -3;
	}
	mh=(MsgHead *)msgptr;
	
	
	/*完成1.检查等待进程队列,若等待队列中有已不存在的进程,则清理等待进程队列*/
	start=(WaitProcQue *)(msgptr + mh->WaitProcStart);
	mac = &mh->FirstProc;
	wpq=start;
	while(1)
	{
		if(*mac < 1) break;
		wpq=start + *mac - 1;
		if(ValidProc(wpq->pid)) {
			*mac = wpq->next;
			continue;
		}
		wpq->ProcType |= M_PROCCHK;
		mac=&wpq->next;
	}
	for(i = 0; i < MaxWaitProcNum;i++) {
		wpq = start + i;
		if(wpq->pid > 0 && !(wpq->ProcType & M_PROCCHK)) {
			memset(wpq, '\0', sizeof(wpq));
		}
		else wpq->ProcType &= ~M_PROCCHK;
	}
	
	/*开始处理超时消息*/
	time(&wrtm);

	mrec=(MsgRec *)(msgptr + mh->RecStart);

	for(i=0;i<mh->MsgNum;i++) {
		mr=mrec + i;
		if(wrtm - mr->m_wrtm >= timeout) break;
	}
	
	if(i >= mh->MsgNum) {
		SLMesgUnLock(msgptr);
		return 1;
		}

	ptr1=buf;
	if(buf) ptr1 = buf + sizeof(MesgStru);
	else ptr1 = NULL;
	
	ptr=msgptr+ mh->DataStart + (mr->Start-1) * mh->BlockSize;
	cb=mr->Start;
	ob=TabRead(msgptr,cb);

	if(!(flag & M_INQ)) {
		TabSet(msgptr,mr->Start,0);
		mh->UnuseBlocks++;
		}

	if(buf) {
		mr1 = (MsgRec *)buf;
		len=mr->m_msglen > mr1->m_msglen ? mr1->m_msglen : mr->m_msglen;
		}
	else {
		mr1 = NULL;
		len = 0;
		}

	i=mh->BlockSize;
	for(;;)
	{
		j=len>i?i:len;
		if(ptr1) {
			memcpy(ptr1,ptr,j);
			memset(ptr,'\0',j);
			ptr1 +=j;
			}
		len-=j;
		ptr+=j;

		if(len<1 || ob<1 )
		{
			mh->MsgNum--;
			time(&wrtm);
			if(buf) {
				len=mr->m_msglen > mr1->m_msglen ? mr1->m_msglen : mr->m_msglen;
				memcpy(mr1, mr, sizeof(MesgStru));
				mst->m_overtime=wrtm - mr->m_wrtm;
				mr1->m_msglen = len;
				}

			if(!(flag & M_INQ))
				while(ob>0) {
					cb=TabRead(msgptr, ob);
					TabSet(msgptr, ob, 0);
					mh->UnuseBlocks++;
					ob=cb;
				}
			if(!(flag & M_INQ)) {
				mrec=(MsgRec *)(msgptr + mh->RecStart);
				i=mh->MsgNum - (mr-mrec);
				if(i>0)
					memcpy((char *)mr,(char *)(mr+1),i * sizeof(MsgRec));
			}
			MsgNotice(msgptr,1,mr1);
			SLMesgUnLock(msgptr);
//			mh->rcvnum++;
//			if(mh->rcvnum % 10000 == 0) printf("rcvnum = %d\n", mh->rcvnum);
			return 0;
		}

		ptr=msgptr+mh->DataStart + (ob - 1)*mh->BlockSize;
		cb=ob;

		ob=TabRead(msgptr,cb);
		if(!(flag & M_INQ)) {
			TabSet(msgptr,cb,0);
			mh->UnuseBlocks++;
			}
		i=mh->BlockSize;
	}
}

⌨️ 快捷键说明

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