Ejemplo n.º 1
0
//---------------------------------------------------------------------
// 从捕捉的事件列表中查找下一个事件
//---------------------------------------------------------------------
static int apu_poll_event(apolld ipd, int *fd, int *event, void **user)
{
	PSTRUCT *ps = PDESC(ipd);
	int revents, eventx = 0, n;
	struct pollfd *pfd;
	if (ps->results <= 0) return -1;
	if (ps->cur_res >= ps->results) return -2;
	pfd = &ps->mresult[ps->cur_res++];

	revents = pfd->revents;
	if (revents & POLLIN) eventx |= APOLL_IN;
	if (revents & POLLOUT)eventx |= APOLL_OUT;
	if (revents & POLLERR)eventx |= APOLL_ERR;

	n = pfd->fd;
	if (ps->fv.fds[n].fd < 0) {
		eventx = 0;
		apu_changes_push(ipd, n, POLLREMOVE);
	}	else {
		eventx &= ps->fv.fds[n].mask;
		if (eventx == 0) {
			apu_poll_set(ipd, n, ps->fv.fds[n].mask);
		}
	}

	if (fd) *fd = n;
	if (event) *event = eventx;
	if (user) *user = ps->fv.fds[n].user;

	return 0;
}
Ejemplo n.º 2
0
//---------------------------------------------------------------------
// 设置 devpoll对象中某文件描述的事件
//---------------------------------------------------------------------
static int apu_poll_set(apolld ipd, int fd, int mask)
{
	PSTRUCT *ps = PDESC(ipd);
	int events = 0;
	int retval;
	int save;

	if (fd >= ps->usr_len) return -1;
	if (ps->fv.fds[fd].fd < 0) return -2;

	save = ps->fv.fds[fd].mask;
	mask =  mask & (APOLL_IN | APOLL_OUT | APOLL_ERR);

	if ((save & mask) != save) 
		apu_changes_push(ipd, fd, POLLREMOVE);

	ps->fv.fds[fd].mask = mask;

	if (mask & APOLL_IN) events |= POLLIN;
	if (mask & APOLL_OUT) events |= POLLOUT;
	if (mask & APOLL_ERR) events |= POLLERR;

	retval = apu_changes_push(ipd, fd, events);

	return retval;
}
Ejemplo n.º 3
0
//---------------------------------------------------------------------
// 调用 devpoll等待函数,捕捉事件
//---------------------------------------------------------------------
static int apu_poll_wait(apolld ipd, int timeval)
{
	PSTRUCT *ps = PDESC(ipd);
	struct dvpoll dvp;
	int retval;

	if (ps->num_chg) {
		apu_changes_apply(ipd);
	}

	dvp.dp_fds = ps->mresult;
	dvp.dp_nfds = ps->max_fd * 2;
	dvp.dp_timeout = timeval;

	if (dvp.dp_nfds > ps->limit) {
		dvp.dp_nfds = ps->limit;
	}

	retval = ioctl(ps->dpfd, DP_POLL, &dvp);

	if (retval < 0) {
		if (errno != EINTR) {
			return -1;
		}
		return 0;
	}

	ps->results = retval;
	ps->cur_res = 0;

	return ps->results;
}
Ejemplo n.º 4
0
//---------------------------------------------------------------------
// 提交 devpoll变更事件
//---------------------------------------------------------------------
static int apu_changes_apply(apolld ipd)
{
	PSTRUCT *ps = PDESC(ipd);
	int num = ps->num_chg;
	if (num == 0) return 0;
	if (pwrite(ps->dpfd, ps->mchange, sizeof(struct pollfd) * num, 0) < 0)
		return -1;
	ps->num_chg = 0;
	return 0;
}
Ejemplo n.º 5
0
//---------------------------------------------------------------------
// 销毁 devpoll描述符
//---------------------------------------------------------------------
static int apu_destroy_pd(apolld ipd)
{
	PSTRUCT *ps = PDESC(ipd);
	iv_destroy(&ps->vresult);
	iv_destroy(&ps->vchange);
	apr_poll_fvdestroy(&ps->fv);

	if (ps->dpfd >= 0) close(ps->dpfd);
	ps->dpfd = -1;
	return 0;
}
Ejemplo n.º 6
0
//---------------------------------------------------------------------
// 初始化 devpoll描述符
//---------------------------------------------------------------------
static int apu_init_pd(apolld ipd, int param)
{
	PSTRUCT *ps = PDESC(ipd);
	int flags = O_RDWR;
	struct rlimit rl;

#ifdef O_CLOEXEC
	flags |= O_CLOEXEC;
#endif

	ps->dpfd = open("/dev/poll", flags);
	if (ps->dpfd < 0) return -1;

#if (!defined(O_CLOEXEC)) && defined(FD_CLOEXEC)
	if (fcntl(ps->dpfd, F_SETFD, FD_CLOEXEC) < 0) {
		close(ps->dpfd);
		ps->dpfd = -1;
		return -2;
	}
#endif

	iv_init(&ps->vresult, NULL);
	iv_init(&ps->vchange, NULL);

	apr_poll_fvinit(&ps->fv, NULL);

	ps->max_fd = 0;
	ps->num_fd = 0;
	ps->max_chg = 0;
	ps->num_chg = 0;
	ps->usr_len = 0;
	ps->limit = 32000;

	if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
		if (rl.rlim_cur != RLIM_INFINITY) {
			if (rl.rlim_cur < 32000) {
				ps->limit = rl.rlim_cur;
			}
		}
	}
	
	if (apu_grow(ps, 4, 4)) {
		apu_destroy_pd(ipd);
		return -3;
	}

	param = param + 1;

	return 0;
}
Ejemplo n.º 7
0
//---------------------------------------------------------------------
// 给 devpoll对象增加一个文件描述
//---------------------------------------------------------------------
static int apu_poll_add(apolld ipd, int fd, int mask, void *user)
{
	PSTRUCT *ps = PDESC(ipd);
	int usr_nlen, i, events;

	if (ps->num_fd >= ps->max_fd) {
		if (apu_grow(ps, ps->max_fd * 2, -1)) return -1;
	}

	if (fd >= ps->usr_len) {
		usr_nlen = fd + 128;
		apr_poll_fvresize(&ps->fv, usr_nlen);
		for (i = ps->usr_len; i < usr_nlen; i++) {
			ps->fv.fds[i].fd = -1;
			ps->fv.fds[i].user = NULL;
			ps->fv.fds[i].mask = 0;
		}
		ps->usr_len = usr_nlen;
	}

	if (ps->fv.fds[fd].fd >= 0) {
		ps->fv.fds[fd].user = user;
		apu_poll_set(ipd, fd, mask);
		return 0;
	}

	events = 0;
	mask = mask & (APOLL_IN | APOLL_OUT | APOLL_ERR);

	if (mask & APOLL_IN) events |= POLLIN;
	if (mask & APOLL_OUT) events |= POLLOUT;
	if (mask & APOLL_ERR) events |= POLLERR;

	ps->fv.fds[fd].fd = fd;
	ps->fv.fds[fd].user = user;
	ps->fv.fds[fd].mask = mask & (APOLL_IN | APOLL_OUT | APOLL_ERR);

	if (apu_changes_push(ipd, fd, events) < 0) {
		return -2;
	}

	ps->num_fd++;

	return 0;
}
Ejemplo n.º 8
0
//---------------------------------------------------------------------
// 在 devpoll对象中删除一个文件描述
//---------------------------------------------------------------------
static int apu_poll_del(apolld ipd, int fd)
{
	PSTRUCT *ps = PDESC(ipd);

	if (ps->num_fd <= 0) return -1;
	if (ps->fv.fds[fd].fd < 0) return -2;
	
	apu_changes_push(ipd, fd, POLLREMOVE);

	ps->num_fd--;
	ps->fv.fds[fd].fd = -1;
	ps->fv.fds[fd].user = NULL;
	ps->fv.fds[fd].mask = 0;

	apu_changes_apply(ipd);

	return 0;
}
Ejemplo n.º 9
0
//---------------------------------------------------------------------
// 增加一个 devpoll变更事件
//---------------------------------------------------------------------
static int apu_changes_push(apolld ipd, int fd, int events)
{
	PSTRUCT *ps = PDESC(ipd);
	struct pollfd *pfd;

	if (fd >= ps->usr_len) return -1;
	if (ps->fv.fds[fd].fd < 0) return -2;
	if (ps->num_chg >= ps->max_chg) {
		if (apu_grow(ps, -1, ps->max_chg * 2)) return -3;
	}

	if (ps->num_chg + 1 >= ps->limit) {
		if (apu_changes_apply(ipd) < 0) return -4;
	}

	pfd = &ps->mchange[ps->num_chg++];
	memset(pfd, 0, sizeof(struct pollfd));

	pfd->fd = fd;
	pfd->events = events;
	pfd->revents = 0;

	return 0;
}
Ejemplo n.º 10
0
/**< 数据处理流程(属于每个线程) */
void* ClientYinLian::YinLianPro(void* pPara)
{
    trace_log(DBG,"start ClientYinLian::YinLianPro()");
    struct pollfd fds[1];
    unsigned char ucRecvbuff[nSglRead*16]={0};
    unsigned char ucRecvTmp[nSglRead]={0};
    int nRecvTmpLen=0;
    int nRead=0,nWrite=0;/**< 读数据、写数据的位置 */
    int nFill=0;
    if(!pPara) {
			return NULL;
		}
    PDESC pDesc=PDESC(pPara);
    if(!pDesc->pCli) {
			return NULL;
		}
    ClientYinLian* pCli=(ClientYinLian*)pDesc->pCli;
    trace_log(DBG,"ClientYinLian::YinLianPro() in while(1),pCli:%p",pCli);
    try {
        while(1) {
            /**< 连接银联 */
            if(!pDesc->bConn || 0 == pDesc->socket_desc) {
                nRead = 0;
                nWrite = 0;
                if(!pCli->Connect(pDesc)) {
                   continue;
                }
                trace_log(DBG,"the cIp[%s] nPort[%d] connect ok",pDesc->cIp,pDesc->nPort);
            }
            fds[0].fd=pDesc->socket_desc;
            fds[0].events = POLLIN|POLLERR|POLLNVAL;
            while (1) {
                /**< 超时断开 */
                time_t curTime = time(0);
							  if(difftime(curTime,pDesc->tIdle) >= 30) { //发个心跳包
                    unsigned char data[2]={0,0};
										PSNDDATA pSndData=new SNDDATA();
										memset(pSndData,0,sizeof(SNDDATA));
										memcpy(pSndData->sndBuff,data,2);
										pSndData->sndLen=2;
										pSndData->tTime=time(0);
										pSndData->isHeartBeat=1;
										pCli->LockListSnd();
										pCli->listSnd.push_back(pSndData);
										pCli->UnLockListSnd();

                } else if(difftime(curTime,pDesc->tIdle) >= nIdleTime) {
                    pDesc->bConn=false;
                    if(pDesc->socket_desc) {
											close(pDesc->socket_desc);
										}
                    pDesc->socket_desc=0;
                    pCli->nConn--;
                    trace_log(ERR,"pDesc->tIdle>nIdleTime[%d]",nIdleTime);
                    break;
                }
                /**< 发送数据 */
								int ret = pCli->SndData(pDesc);
                if(ret == 0) {
                    trace_log(ERR,"pCli->SndData ERR");
                    break;
                } else if(ret == 2) {
									//trace_log(DBG,"Send Success HeadtBeat,No Read...");
									continue;
								}

                /**< 错误处理 */
                int retval = poll(fds, 1, 5);
                if (retval < 0) {
                    pDesc->bConn=false;
                    if(pDesc->socket_desc) {
											close(pDesc->socket_desc);
										}
                    pDesc->socket_desc=0;
                    pCli->nConn--;
                    trace_log(ERR,"retval = poll()<0");
                    break;
                }
                if (fds[0].revents & POLLERR||fds[0].revents & POLLNVAL) {
                    pDesc->bConn=false;
                    if(pDesc->socket_desc) {
											close(pDesc->socket_desc);
										}
                    pDesc->socket_desc=0;
                    pCli->nConn--;
                    trace_log(ERR,"retval = poll():POLLERR||POLLNVAL");
                    break;
                }
                /**< 读数据 */
                if (fds[0].revents & POLLIN) {
                    trace_log(DBG,"retval = poll():POLLIN,nRead:%d,nWrite:%d,retval:%d",nRead,nWrite,retval);
                    pDesc->tIdle=time(0);
                    nFill = (nRead > nWrite) ? ( nRead - nWrite):(nSglRead*16 + nWrite - nRead);
                    if(nFill > nSglRead) {
                        trace_log(DBG," START RecvData(pDesc,ucRecvTmp,nRecvTmpLen)");
                        nRecvTmpLen=sizeof(ucRecvTmp);
                        if(pCli->RecvData(pDesc,ucRecvTmp,nRecvTmpLen)) {
                            int nRight=nSglRead * 16 - nWrite;
                            if(nRight > nRecvTmpLen) {
                                memcpy(ucRecvbuff+nWrite,ucRecvTmp,nRecvTmpLen);
                                nWrite += nRecvTmpLen;
                            } else {
                                memcpy(ucRecvbuff+nWrite,ucRecvTmp,nRight);
                                nWrite = nRecvTmpLen-nRight;
                                memcpy(ucRecvbuff,ucRecvTmp+nRight,nWrite);
                            }
                            trace_log(DBG,"RecvData(pDesc,ucRecvTmp,nRecvTmpLen:%d) OK,nRead:%d,nWrite:%d",
															nRecvTmpLen,nRead,nWrite);
                        } else {
                            trace_log(DBG,"RecvData(pDesc,ucRecvTmp,nRecvTmpLen) fail");
                            break;
                        }
                    }
                }

								/**< 解包 */
                pCli->UpPack(ucRecvbuff,nWrite,nRead);
            }
        }
        return NULL;
    }catch(...){
        trace_log(ERR,"Error in ClientYinLian::YinLianPro()");
    }
    return NULL;
}