- 论坛徽章:
- 0
|
最近为了移植windows网络SDK代码到Linux下,在保持代码的统一性前提下,模拟了windows WSAEVENT的相关函数, 幸运的是在该SDK中: DWORD
WSAWaitForMultipleEvents(DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable);
参数fWaitAll, 以及fAlertable都是使用FALSE. 要是有一个TRUE的话就难办了
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#define __USE_XOPEN
#include <sys/poll.h>
#define TRUE 1
#define FALSE 0
#define BOOL int
#define DWORD unsigned int
#define FAR
#define WSA_INVALID_PARAMETER ((DWORD)-3L)
#define WSA_INVALID_EVENT ((DWORD)-2L)
#define WSA_WAIT_FAILED ((DWORD)-1L)
#define WSA_WAIT_TIMEOUT ((DWORD)0)
#define WSA_WAIT_EVENT_0 ((DWORD)1)
#define FLG_WSA_EVENT 0
typedef struct __LNX_EVENT
{
int flags;
int lnx_fd[2];
pthread_mutex_t mutex;
}LNX_EVENT;
typedef void* HANDLE;
typedef LNX_EVENT* WSAEVENT;
HANDLE WSACreateEvent(void)
{
LNX_EVENT* event = (LNX_EVENT*)malloc(sizeof(LNX_EVENT));
int retval = pipe(event->lnx_fd);
if(retval < 0)
{
free(event);
return NULL;
}
event->flags = FLG_WSA_EVENT;
pthread_mutex_init(&(event->mutex), NULL);
return (HANDLE)event;
}
BOOL WSASetEvent(HANDLE hEvent)
{
LNX_EVENT* event = (LNX_EVENT*)hEvent;
if(event->flags != FLG_WSA_EVENT)
{
return FALSE;
}
pthread_mutex_lock(&(event->mutex));
struct pollfd fdarray[2];
memset(fdarray, 0x0, sizeof(struct pollfd) * 2);
fdarray[0].fd = event->lnx_fd[0];
fdarray[0].events = POLLRDNORM;
fdarray[1].fd = event->lnx_fd[1];
fdarray[1].events = POLLWRNORM;
int ret = poll(&fdarray[0], 1, 0);
if(ret > 0 && (fdarray[0].revents & POLLRDNORM))
{
char buffer[256] = {0};
read(event->lnx_fd[0], buffer, 1024);
}
ret = poll(&fdarray[1], 1, 0);
if(ret <= 0)
{
pthread_mutex_unlock(&(event->mutex));
return FALSE;
}
char w_signal = 'h';
BOOL bRet = write(event->lnx_fd[1], &w_signal, 1) == 1 ? TRUE : FALSE;
pthread_mutex_unlock(&(event->mutex));
return bRet;
}
BOOL WSAResetEvent(HANDLE hEvent)
{
BOOL bRet = FALSE;
LNX_EVENT* event = (LNX_EVENT*)hEvent;
if(event->flags != FLG_WSA_EVENT)
{
return FALSE;
}
pthread_mutex_lock(&(event->mutex));
struct pollfd fdarray;
memset(&fdarray, 0x0, sizeof(struct pollfd));
fdarray.fd = event->lnx_fd[0];
fdarray.events = POLLRDNORM;
int ret = poll(&fdarray, 1, 0);
if(ret > 0 && (fdarray.revents & POLLRDNORM))
{
char buffer[256] = {0};
bRet = read(event->lnx_fd[0], buffer, 1024) > 0 ? TRUE : FALSE;
fprintf(stderr, "Reset the send buffer: %s\n", buffer);
}
pthread_mutex_unlock(&(event->mutex));
return bRet;
}
BOOL WSACloseEvent(HANDLE hEvent)
{
LNX_EVENT* event = (LNX_EVENT*)hEvent;
if(event->flags != FLG_WSA_EVENT)
{
return FALSE;
}
close(event->lnx_fd[0]);
close(event->lnx_fd[1]);
pthread_mutex_destroy(&(event->mutex));
free(event);
return TRUE;
}
DWORD WSAWaitForMultipleEvents(DWORD cEvents, const WSAEVENT FAR *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable)
{
if(cEvents <= 0 || lphEvents == NULL || fWaitAll == TRUE || fAlertable == TRUE)
{
return WSA_INVALID_PARAMETER;
}
struct pollfd fdarray[cEvents];
memset(fdarray, 0x0, sizeof(struct pollfd) * cEvents);
int index = 0;
for(; index < cEvents; index++)
{
if(lphEvents[index]->flags != FLG_WSA_EVENT)
{
return WSA_INVALID_EVENT;
}
fdarray[index].fd = lphEvents[index]->lnx_fd[0];
fdarray[index].events = POLLRDNORM;
}
int ret = poll(fdarray, cEvents, dwTimeout);
if(ret > 0)
{
for(index = 0; index < cEvents; index++)
{
if(fdarray[index].revents & POLLRDNORM)
{
return WSA_WAIT_EVENT_0 + index;
}
}
}
else if(ret == 0)
{
return WSA_WAIT_TIMEOUT;
}
return WSA_WAIT_FAILED;
}
|
[ 本帖最后由 飞雪横天 于 2009-3-19 21:19 编辑 ] |
|