Jabberd2源代码分析: MIO

    技术2022-05-19  18

    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结构体中定义了统一的API,各个IO复用技术实现这些接口

     

     

    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函数中设置的。


    最新回复(0)