MIO用于封装select epool poll kqueue使统一API。
可以再不同的平台选择对应的IO复用技术
typedef struct mio_st
{
void (*mio_free)(struct mio_st **m);
struct mio_fd_st *(*mio_listen)(struct mio_st **m, int port, char *sourceip,
mio_handler_t app, void *arg);
struct mio_fd_st *(*mio_connect)(struct mio_st **m, int port, char *hostip,
char *srcip, mio_handler_t app, void *arg);
struct mio_fd_st *(*mio_register)(struct mio_st **m, int fd,
mio_handler_t app, void *arg);
void (*mio_app)(struct mio_st **m, struct mio_fd_st *fd,
mio_handler_t app, void *arg);
void (*mio_close)(struct mio_st **m, struct mio_fd_st *fd);
void (*mio_write)(struct mio_st **m, struct mio_fd_st *fd);
void (*mio_read)(struct mio_st **m, struct mio_fd_st *fd);
void (*mio_run)(struct mio_st **m, int timeout);
} **mio_t;
mio_t mio_new(int maxfd)
根据不同操作系统采用不同的初始化方法,有:
mio_t mio_kqueue_new(int maxfd);
mio_t mio_epoll_new(int maxfd);
mio_t mio_poll_new(int maxfd);
mio_t mio_select_new(int maxfd);
mio_t mio_wsasync_new(int maxfd);
这些mio_*_new函数又调用了mio_impl.h中的_mio_new函数,mio_impl.h文件中将各个IO复用技术差异部分使用宏来定义。
mio_fd_t mio_connect(mio_t m, int port, char *hostip, char *srcip, mio_handler_t app, void *arg)
mio_connect函数实现了异步的connect,在该函数中创建socket后,将socket句柄设置为非阻塞,然后调用connect函数,由于socket被设置为非阻塞,不管连接是否成功connect都会立即返回。然后将创建的socket句柄加入到mio_t中,用于监视这个句柄。传入的参数app和arg并不会立刻被调用。而是调用宏ACT时调用已设置的函调函数app。
#define ACT(m,f,a,d) (*(FD(m,f)->app))(m,a,&FD(m,f)->mio_fd,d,FD(m,f)->arg)
调用用户设置的回调函数,并且传入用户设置的参数
void _mio_write(mio_t m, mio_fd_t fd)
如果fd状态为type_NORMAL(如果socket已经连接成功), 调用已设置的回调函数。该回调函数是在mio_connect和mio_listen函数中设置的。