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

📄 myhandleset.c

📁 sourceforge历史版本完整下载: http://sourceforge.net/project/showfiles.php?group_id=202044 提供了基于b树索引算法的文件数据数据
💻 C
字号:
/*
*
*myhandleSet.c fd集合 lin shao chuan
*
*/


#include "myhandleSet.h"

#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>

#include "myrbtree.h"
#include "mymutex.h"


typedef struct __myhandleSet_t_
{
	fd_set read_mask;
	fd_set read_mask_signaled;
	int read_size;

	fd_set write_mask;
	fd_set write_mask_signaled;
	int write_size;

	fd_set exception_mask;
	fd_set exception_mask_signaled;
	int exception_size;

	HMYRBTREE hfdtable;	

	HMYMEMPOOL hm;

	HMYMUTEX protecter;
}myhandleSet_t;


/*
*
*1 表示 key1 比 key2 大
*0 表示 key1 比 key2 小 
*
*/
static __INLINE__ int handle_rbtree_compare(const void * key1, const void * key2)
{
	return key1 > key2;
}

static __INLINE__ void destroy(myhandleSet_t * hset)
{
	assert(hset);

	MyMutexLock(hset->protecter);

	if(hset->hfdtable)
		MyRBTreeDestruct(hset->hfdtable);

	MyMutexUnLock(hset->protecter);

	MyMutexDestruct(hset->protecter);

	MyMemPoolFree(hset->hm, hset);
}


/*
*
*创建
*
*/
HMYHANDLESET MyHandleSetConstruct(HMYMEMPOOL hm)
{
	myhandleSet_t * hset = (myhandleSet_t *)MyMemPoolMalloc(hm, sizeof(*hset));
	if(NULL == hset)
		return NULL;

	hset->hm = hm;
	hset->hfdtable = MyRBTreeConstruct(hm, handle_rbtree_compare);
	hset->protecter = MyMutexConstruct(hm);
	if(NULL == hset->hfdtable || NULL == hset->protecter)
	{
		destroy(hset);
		return NULL;
	}
	
	FD_ZERO(&hset->read_mask);
	FD_ZERO(&hset->read_mask_signaled);
	hset->read_size = 0;

	FD_ZERO(&hset->write_mask);
	FD_ZERO(&hset->write_mask_signaled);
	hset->write_size = 0;

	FD_ZERO(&hset->exception_mask);
	FD_ZERO(&hset->exception_mask_signaled);
	hset->exception_size = 0;
	
	return (HMYHANDLESET)hset;
}

/*
*
*销毁
*
*/
void MyHandleSetDestruct(HMYHANDLESET hs)
{
	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return;

	destroy(hset);
}

/*
*
*添加一个fd
*@retval:
	0:成功
	-1:添加全部失败
	-2:添加读失败
	-3:添加写失败
	-4:添加异常失败
*
*/
int MyHandleSetFdSet(HMYHANDLESET hs, int fd, unsigned long mask)
{
	int ret = 0;
	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return -1;

	assert(hset->hfdtable);

	if(0 != MyMutexLock(hset->protecter))
		return -1;

	if(mask & E_FD_READ)
	{
		if(hset->read_size >= FD_SETSIZE)
		{
			ret = -2;
			goto MyHandleSetFdSet_end_;
		}

		FD_SET(fd, &hset->read_mask);
		hset->read_size = (fd >= hset->read_size)?(fd+1):hset->read_size;
	}
	else if(mask & E_FD_WRITE)
	{
		if(hset->write_size >= FD_SETSIZE)
		{
			ret = -3;
			goto MyHandleSetFdSet_end_;
		}

		FD_SET(fd, &hset->write_mask);
		hset->write_size = (fd >= hset->write_size)?(fd+1):hset->write_size;
	}
	else if(mask & E_FD_EXCEPTION)
	{
		if(hset->exception_size >= FD_SETSIZE)
		{
			ret = -4;
			goto MyHandleSetFdSet_end_;
		}

		FD_SET(fd, &hset->exception_mask);
		hset->exception_size = (fd >= hset->exception_size)?(fd+1):hset->exception_size;
	}

	MyRBTreeInsertUnique(hset->hfdtable, (void *)fd, (void *)mask);

MyHandleSetFdSet_end_:

	MyMutexUnLock(hset->protecter);
	return ret;
}

/*
*
*删除加一个fd
*
*/
void MyHandleSetDelFd(HMYHANDLESET hs, int fd)
{
	unsigned long mask = 0;
	HMYRBTREE_ITER it = NULL;
	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return;

	if(0 != MyMutexLock(hset->protecter))
		return;

	//找出fd的信息
	it = MyRBTreeSearch(hset->hfdtable, (void *)fd);
	mask = (unsigned long)MyRBTreeGetIterData(it);
	
	//从表中删除
	MyRBTreeDelIter(hset->hfdtable, it, NULL, NULL);
	
	//根据需要从相应的集合里删除
	if(mask & E_FD_READ)
	{
		FD_CLR(fd, &hset->read_mask);
		hset->read_size --;
		if(hset->read_size < 0)
			hset->read_size = 0;
	}
	else if(mask & E_FD_WRITE)
	{
		FD_CLR(fd, &hset->write_mask);
		hset->write_size --;
		if(hset->write_size < 0)
			hset->write_size = 0;
	}
	else if(mask & E_FD_EXCEPTION)
	{
		FD_CLR(fd, &hset->exception_mask);
		hset->exception_size --;
		if(hset->exception_size < 0)
			hset->exception_size = 0;
	}

	MyMutexUnLock(hset->protecter);
}

/*
*
*select
*@param
	timeout:超时,null表示无限等待
*@retval
	0:表示超时 非-1则表示发生事件的句柄数 -1:表示失败
*
*/
int MyHandleSetSelect(HMYHANDLESET hs, struct timeval * timeout)
{	
	int nfds = 0;

	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return -1;

	if(0 != MyMutexLock(hset->protecter))
		return -1;

	FD_ZERO(&hset->read_mask_signaled);
	FD_ZERO(&hset->write_mask_signaled);
	FD_ZERO(&hset->exception_mask_signaled);

	hset->read_mask_signaled = hset->read_mask;
	hset->write_mask_signaled = hset->write_mask;
	hset->exception_mask_signaled = hset->exception_mask;

	nfds = (hset->read_size > hset->write_size)?(hset->read_size > hset->exception_size ? hset->read_size:hset->exception_size):(hset->write_size > hset->exception_size ? hset->write_size:hset->exception_size);

	MyMutexUnLock(hset->protecter);

	return select(nfds,
		&hset->read_mask_signaled,
		&hset->write_mask_signaled,
		&hset->exception_mask_signaled,
		timeout);
}

/*
*
*取出所有发生事件的fd,并清空当前发生事件的fd集合
*@param
	hvRead:表示可读的fd集合
	hvWrite:表示可写的fd集合
	hvException:表示出错的fd集合
*
*/	
void MyHandleSetGetAllSignalFd(HMYHANDLESET hs,
	HMYVECTOR read_set,
	HMYVECTOR write_set,
	HMYVECTOR exception_set)
{
	/**
	*
	*ACE实现了直接从fd_set里取出发生事件的fd,
	*而不是循环的使用FD_ISSET找出发生事件的fd.
	*
	*注:<sys/select.h> <bits/select.h> 里fd_set操作的实现根据gcc
	*版本不同,实现也不同.而且有其它宏来决定fd_set相关操作的具体实现
	*
	*ACE的关于这一块的代码也暂时没有看懂.
	*
	*todo: help me!
	*
	**/

	HMYRBTREE_ITER it = NULL;
	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return;

	if(0 != MyMutexLock(hset->protecter))
		return;

	for(it = MyRBTreeBegin(hset->hfdtable); 
		it != NULL; 
		it = MyRBTreeGetNext(it))
	{
		int fd = (int)MyRBTreeGetIterKey(it);

		if(FD_ISSET(fd, &hset->read_mask_signaled) && read_set)
			MyVectorAdd(read_set, (void *)fd, 0);
		if(FD_ISSET(fd, &hset->write_mask_signaled) && write_set)
			MyVectorAdd(write_set, (void *)fd, 0);
		if(FD_ISSET(fd, &hset->exception_mask_signaled) && exception_set)
			MyVectorAdd(exception_set, (void *)fd, 0);
	}

	FD_ZERO(&hset->read_mask_signaled);
	FD_ZERO(&hset->write_mask_signaled);
	FD_ZERO(&hset->exception_mask_signaled);

	MyMutexUnLock(hset->protecter);
}

/*
*
*判断fd是否发生mask中指定的事件,并从相应的集合中删除fd
*
*/	
unsigned long MyHandleSetIsSet(HMYHANDLESET hs, int fd, unsigned long mask)
{
	unsigned long mask_ret = 0;
	myhandleSet_t * hset = (myhandleSet_t *)hs;
	if(NULL == hset)
		return 0;

	if(0 != MyMutexLock(hset->protecter))
		return 0;

	if((mask & E_FD_READ) && FD_ISSET(fd, &hset->read_mask_signaled))
	{
		mask_ret |= E_FD_READ;
		FD_CLR(fd, &hset->read_mask_signaled);
	}

	if((mask & E_FD_WRITE) && FD_ISSET(fd, &hset->write_mask_signaled))
	{
		mask_ret |= E_FD_WRITE;
		FD_CLR(fd, &hset->write_mask_signaled);
	}

	if((mask & E_FD_EXCEPTION) && FD_ISSET(fd, &hset->exception_mask_signaled))
	{
		mask_ret |= E_FD_EXCEPTION;
		FD_CLR(fd, &hset->exception_mask_signaled);
	}

	MyMutexUnLock(hset->protecter);

	return mask_ret;
}


















⌨️ 快捷键说明

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