修改state-thread库

最近在使用协程的开发php扩展,对比了一些协程库,发现state-thread是一个不错的协程开发框架,于是将其改造为rapidsvr(由于存在编译和性能问题),同时也整理了相应的api文档。(state-thread背景:其诞生最初是由网景(Netscape)公司的MSPR(Netscape Portable Runtime library)项目中剥离出来,后由SGI(Silicon Graphic Inc)还有Yahoo!公司(前者是主力)开发维护的独立线程库。)
废话不多说,先上example(如何用state-thread写server):

void *do_resolve(void *host)  
{  
	struct in_addr addr;  

	/* Use dns_getaddr() instead of gethostbyname to get IP address */  
	if (dns_getaddr(host, &addr, TIMEOUT) < 0) {  
		fprintf(stderr, "dns_getaddr: can't resolve %s: ", (char *)host);  
		if (h_errno == NETDB_INTERNAL) {
			perror("");  
		}
		else {
			perror("");  
		}
	} else {
		printf("%-40s %s\n", (char *)host, inet_ntoa(addr));  
	}

	return NULL;  
}
int main(int argc, char *argv[])  
{  
	int i;  
	if (argc < 2) {  
		fprintf(stderr, "Usage: %s <hostname1> [<hostname2>] ...\n", argv[0]);  
		exit(1);  
	}  

	if (st_init() < 0) {  
		perror("st_init failed");  
		exit(1);
	}

	for (i = 1; i < argc; i++) {  
		if (st_thread_create(do_resolve, argv[i], 0, 0) == NULL) {  
			perror("st_thread_create failed");  
			exit(1);  
		}  
	}  

	st_thread_exit(NULL);  

	/* NOTREACHED */  
	return 1;  
}  

mifast的api – 结构体

(1)st_thread_t
定义:typedef void * st_thread_t;
说明:线程类型
(2)st_cond_t
定义:typedef void * st_cond_t;
(3)st_mutex_t
定义:typedef void * st_mutex_t;
(4)st_utime_t
定义:typedef unsigned long long st_utime_t;
(5)st_netfd_t
定义:typedef void * st_netfd_t;
(6)st_switch_cb_t
定义:typedef void(* st_switch_cb_t)(void);

mifast的api – 初始化函数

(1)st_init()
定义:int st_init(void);
返回:成功完成后,返回值0。否则,返回值-1,并设置errno来指示错误。
(2)st_getfdlimit()
定义:int st_getfdlimit(void);
说明:返回调用进程可以打开的最大文件描述符数。
(3)st_set_eventsys()
定义:int st_set_eventsys(int eventsys);
说明:设置事件通知机制。其中eventsys值如下:
ST_EVENTSYS_DEFAULT 使用默认事件通知机制。通常它是select,但是如果库被编译了定义的USE_POLL宏,则默认是poll。
ST_EVENTSYS_SELECT 使用select作为事件通知机制。
ST_EVENTSYS_POLL 使用轮询作为事件通知机制。 ST_EVENTSYS_ALT 使用替代事件通知机制。所选择的实际机制取决于操作系统支持。例如:如果支持,则在Linux上使用epoll,并在FreeBSD / OpenBSD上使用kqueue。如果操作系统不支持备用事件通知机制,则设置ST_EVENTSYS_ALT不起作用,并且将使用ST_EVENTSYS_DEFAULT机制。 (4)st_get_eventsys()
定义:int st_get_eventsys(void);
说明:返回标识状态线程库使用的事件通知机制的整数值。
(5)st_get_eventsys_name()
定义:const char * st_get_eventsys_name(void);
说明:返回状态线程库使用的事件通知机制的名称,可能返回”select”,”poll”,”kqueue”或”epoll”。
(6)st_set_switch_in_cb(), st_set_switch_out_cb()
定义:
st_switch_cb_t st_set_switch_in_cb(st_switch_cb_t cb);
st_switch_cb_t st_set_switch_out_cb(st_switch_cb_t cb);
说明:这些函数设置回调,当线程分别恢复和停止时,被调用后任何线程切换将调用回调,使用NULL指针来禁用回调(这是默认值)。

mifast的api – 线程

(1)st_thread_create ()
定义:st_thread_t st_thread_create(void start)(void * arg),void * arg, int joinable,int stack_size);
说明:void start)(void * arg) 函数指针
void * arg 函数参数
joinable 线程是否可以有子线程
stack_size 堆栈大小(IA-64上的默认堆栈大小为128 KB,所有其他平台的默认堆栈大小为64 KB)
(2)st_thread_exit()
定义:void st_thread_exit(void * retval);
说明:终止调用线程 。
(3)st_thread_join()
定义:int st_thread_join(st_thread_t thread,void ** retvalp);
说明:等待调用线程,直到指定的线程终止 。 (4)st_thread_self()
定义:st_thread_t st_thread_self(void);
(5)st_thread_interrupt()
定义:void st_thread_interrupt(st_thread_t thread);
说明:中断一个目标线程。
(6)st_sleep(),st_usleep()
定义:int st_sleep(int secs);
int st_usleep(st_utime_t usecs);
说明:st_sleep 等待秒,st_usleep 等待微秒。
(7)st_randomize_stacks()
定义:int st_randomize_stacks(int on);
说明:随机化时,新的堆栈被分配一页为容纳进行随机化。

mifast的api – IO功能

目前大部分大多数状态线程库I/O函数看起来像对应的C库函数,其中两个重点处理:st_netfd_t,st_utime_t,对应C库函数的句柄fd和time_t;
(1)st_netfd_open()
定义:st_netfd_t st_netfd_open(int osfd);
说明:打开句柄,任何开放的OS文件描述符; 可以通过调用函数获得,包括但不限于管道,套接字,套接字,fcntl,dup等。
(2)st_netfd_open_socket()
定义:st_netfd_t st_netfd_open_socket(int osfd);
说明:此函数创建一个新的文件描述符对象,类型为 st_netfd_t,表示网络通信的开放端点。
与可能用于任何来源的OS文件描述符的st_netfd_open()函数不同,st_netfd_open_socket()只能在套接字上使用。它比st_netfd_open()更有效。
(3)st_netfd_free()
定义:void st_netfd_free(st_netfd_t fd);
说明:释放文件描述符对象,而不关闭底层的操作系统文件描述符。
(4)st_netfd_close()
定义:int st_netfd_close(st_netfd_t fd);
说明:关闭文件描述符。
(5)st_netfd_fileno()
定义:int st_netfd_fileno(st_netfd_t fd);
说明:返回底层操作系统文件描述符。
(6)st_netfd_setspecific() 定义:void st_netfd_setspecific(st_netfd_t fd,void * value, void(* destructor)(void *));
说明:设置每个描述符的私有数据。
fd 一个有效的文件描述符对象标识符;
value 每个描述符的私有数据,或更可能的是指向与指定的文件描述符对象相关联的数据的指针;
destructor 为与fd关联的专用数据指定可选的析构函数。该函数可以指定为NULL。如果值不为NULL,则在释放文件描述符对象(参见st_netfd_free()和 st_netfd_close())时,将使用值作为参数调用此析构函数;
(7)st_netfd_getspecific()
定义:void * st_netfd_getspecific(st_netfd_t fd);
说明:获取每个描述符的私有数据。
(8)st_netfd_serialize_accept()
定义:int st_netfd_serialize_accept(st_netfd_t fd);
说明:对指定的文件描述符对象的 所有后续accept(3)调用进行序列化;
注意:在某些平台上(例如,Solaris 2.5和可能的其他SVR4实现) 接受来自同一监听套接字上不同进程的调用(请参阅bind,listen)必须被序列化。此函数将使指定的文件描述符对象上由st_accept()进行的所有后续accept调用序列化;在通过fork创建多个服务器进程之前,必须调用st_netfd_serialize_accept()。如果应用程序没有创建多个进程来接受同一侦听套接字上的网络连接,则无需调用此功能;决定是否序列化接受是棘手的。在某些平台上(IRIX,Linux),它根本不需要,而 st_netfd_serialize_accept()是一个无操作的。在其他平台上,这取决于操作系统的版本(Solaris 2.6不需要,但早期版本)。序列化接受确实会导致轻微的性能损失,因此只有在必要时才启用它。请阅读系统的手册页(accept),然后选择 查看系统是否需要接受序列化。
(9)st_netfd_poll()
定义:int st_netfd_poll(st_netfd_t fd,int how,st_utime_t timeout);
说明:POLLIN fd是可读的;
POLLOUT fd是可写的;
POLLPRI fd有异常情况。
(10)st_accept()
定义:st_netfd_t st_accept(st_netfd_t fd,struct sockaddr * addr,int * addrlen, st_utime_t timeout); 说明:对应通用的accept函数。
fd 接受新连接的会合套接字的文件描述符对象标识符;
addr struct sockaddr *的结构体;
addrlen struct sockaddr的长度;
timeout 类型为st_utime_t的值,指定完成接受操作的时间限制。
(11)st_connect()
定义:int st_connect(st_netfd_t fd,struct sockaddr * addr,int addrlen, st_utime_t timeout);
说明:对应通用的connect函数。
(12)st_read()
定义:ssize_t st_read(st_netfd_t fd,void * buf,size_t nbyte,st_utime_t timeout);
说明:对应通用的read函数
(13)其他read函数st_read_fully(),st_read_resid(),st_readv(),st_readv_resid()
说明:对应通用的read函数,其中注意st_readv和st_readv_resid的struct iovec参数。
(14)st_write()
定义:ssize_t st_write(st_netfd_t fd,const void * buf,size_t nbyte, st_utime_t timeout);
说明:对应通用的write函数。
(15)其他write函数st_write_resid(),st_writev(),st_writev_resid()
说明:对应通用的write函数,其中注意st_writev和st_writev_resid的struct iovec参数。
(16)st_recvfrom(),st_sendto()
定义:int st_recvfrom(st_netfd_t fd,void * buf,int len,struct sockaddr * from, int * fromlen,st_utime_t timeout);
int st_sendto(st_netfd_t fd,const void * msg,int len,struct sockaddr * to, int tolen,st_utime_t timeout);
说明:使用UDP套接字的文件描述符对象接收指定数量的字节 (17)st_recvmsg(),st_sendmsg()
定义:int st_recvmsg(st_netfd_t fd,struct msghdr * msg,int flags, st_utime_t timeout); int st_sendmsg(st_netfd_t fd,const struct msghdr * msg,int flags, st_utime_t timeout); 定义:表示UDP套接字的文件描述符对象,该操作由msg参数控制;如果基础OS套接字上没有缓冲空间可用于保存要发送的消息,则st_sendmsg()将阻塞调用线程,直到空间可用,发生超时或发生错误。
(18)st_open()
定义:st_netfd_t st_open(const char * path,int oflags,mode_t mode);
说明:打开一个文件。
(19)st_poll()
定义:int st_poll(struct pollfd * pds,int npds,st_utime_t timeout);

备注

(1)st_netfd_t 结构体
typedef struct _st_netfd { int osfd; /* Underlying OS file descriptor / int inuse; / In-use flag */ void private_data; / Per descriptor private data / _st_destructor_t destructor; / Private data destructor function */ void aux_data; / Auxiliary data for internal use */ struct _st_netfd next; / For putting on the free list */ } _st_netfd_t;