| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #ifndef HW_LOOP_H_
- #define HW_LOOP_H_
- #include "hdef.h"
- BEGIN_EXTERN_C
- #include "htime.h"
- #include "array.h"
- #include "list.h"
- #include "heap.h"
- #include "queue.h"
- #include "hbuf.h"
- typedef struct hloop_s hloop_t;
- typedef struct hevent_s hevent_t;
- typedef struct hidle_s hidle_t;
- typedef struct htimer_s htimer_t;
- typedef struct htimeout_s htimeout_t;
- typedef struct hperiod_s hperiod_t;
- typedef struct hio_s hio_t;
- typedef void (*hevent_cb) (hevent_t* ev);
- typedef void (*hidle_cb) (hidle_t* idle);
- typedef void (*htimer_cb) (htimer_t* timer);
- typedef void (*hio_cb) (hio_t* io);
- typedef void (*haccept_cb) (hio_t* io, int connfd);
- typedef void (*hconnect_cb) (hio_t* io);
- typedef void (*hread_cb) (hio_t* io, void* buf, int readbytes);
- typedef void (*hwrite_cb) (hio_t* io, const void* buf, int writebytes);
- typedef void (*hclose_cb) (hio_t* io);
- typedef enum {
- HEVENT_TYPE_NONE = 0,
- HEVENT_TYPE_IDLE = 0x00000010,
- HEVENT_TYPE_TIMEOUT = 0x00000100,
- HEVENT_TYPE_PERIOD = 0x00000200,
- HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
- HEVENT_TYPE_IO = 0x00001000,
- } hevent_type_e;
- #define HEVENT_LOWEST_PRIORITY (-5)
- #define HEVENT_LOW_PRIORITY (-3)
- #define HEVENT_NORMAL_PRIORITY 0
- #define HEVENT_HIGH_PRIORITY 3
- #define HEVENT_HIGHEST_PRIORITY 5
- #define HEVENT_PRIORITY_SIZE (HEVENT_HIGHEST_PRIORITY-HEVENT_LOWEST_PRIORITY+1)
- #define HEVENT_PRIORITY_INDEX(priority) (priority-HEVENT_LOWEST_PRIORITY)
- #define HEVENT_FLAGS \
- unsigned destroy :1; \
- unsigned active :1; \
- unsigned pending :1;
- #define HEVENT_FIELDS \
- hloop_t* loop; \
- hevent_type_e event_type; \
- uint64_t event_id; \
- hevent_cb cb; \
- void* userdata; \
- int priority; \
- struct hevent_s* pending_next; \
- HEVENT_FLAGS
- struct hevent_s {
- HEVENT_FIELDS
- };
- struct hidle_s {
- HEVENT_FIELDS
- uint32_t repeat;
- //private:
- struct list_node node;
- };
- #define HTIMER_FIELDS \
- HEVENT_FIELDS \
- uint32_t repeat; \
- uint64_t next_timeout; \
- struct heap_node node;
- struct htimer_s {
- HTIMER_FIELDS
- };
- struct htimeout_s {
- HTIMER_FIELDS
- uint32_t timeout; \
- };
- struct hperiod_s {
- HTIMER_FIELDS
- int8_t minute;
- int8_t hour;
- int8_t day;
- int8_t week;
- int8_t month;
- };
- QUEUE_DECL(offset_buf_t, write_queue);
- typedef enum {
- HIO_TYPE_UNKNOWN = 0,
- HIO_TYPE_STDIN = 0x00000001,
- HIO_TYPE_STDOUT = 0x00000002,
- HIO_TYPE_STDERR = 0x00000004,
- HIO_TYPE_STDIO = HIO_TYPE_STDIN|HIO_TYPE_STDOUT|HIO_TYPE_STDERR,
- HIO_TYPE_FILE = 0x00000010,
- HIO_TYPE_TCP = 0x00000100,
- HIO_TYPE_UDP = 0x00001000,
- HIO_TYPE_IP = 0x00010000,
- HIO_TYPE_SOCKET = HIO_TYPE_TCP|HIO_TYPE_UDP|HIO_TYPE_IP
- } hio_type_e;
- struct hio_s {
- HEVENT_FIELDS
- unsigned ready :1;
- unsigned closed :1;
- unsigned accept :1;
- unsigned connect :1;
- unsigned connectex :1; // for ConnectEx/DisconnectEx
- unsigned recv :1;
- unsigned send :1;
- unsigned recvfrom :1;
- unsigned sendto :1;
- int fd;
- hio_type_e io_type;
- int error;
- int events;
- int revents;
- struct sockaddr* localaddr;
- struct sockaddr* peeraddr;
- hbuf_t readbuf; // for hread
- struct write_queue write_queue; // for hwrite
- // callbacks
- hread_cb read_cb;
- hwrite_cb write_cb;
- hclose_cb close_cb;
- haccept_cb accept_cb;
- hconnect_cb connect_cb;
- //private:
- int event_index[2]; // for poll,kqueue
- void* hovlp; // for iocp/overlapio
- };
- typedef enum {
- HLOOP_STATUS_STOP,
- HLOOP_STATUS_RUNNING,
- HLOOP_STATUS_PAUSE
- } hloop_status_e;
- ARRAY_DECL(hio_t*, io_array);
- struct hloop_s {
- hloop_status_e status;
- time_t start_time;
- // hrtime: us
- uint64_t start_hrtime;
- uint64_t end_hrtime;
- uint64_t cur_hrtime;
- uint64_t loop_cnt;
- void* userdata;
- //private:
- // events
- uint64_t event_counter;
- uint32_t nactives;
- uint32_t npendings;
- // pendings: with priority as array.index
- hevent_t* pendings[HEVENT_PRIORITY_SIZE];
- // idles
- struct list_head idles;
- uint32_t nidles;
- // timers
- struct heap timers;
- uint32_t ntimers;
- // ios: with fd as array.index
- struct io_array ios;
- uint32_t nios;
- void* iowatcher;
- };
- // loop
- int hloop_init(hloop_t* loop);
- //void hloop_cleanup(hloop_t* loop);
- int hloop_run(hloop_t* loop);
- int hloop_stop(hloop_t* loop);
- int hloop_pause(hloop_t* loop);
- int hloop_resume(hloop_t* loop);
- static inline void hloop_update_time(hloop_t* loop) {
- loop->cur_hrtime = gethrtime();
- }
- static inline time_t hloop_now(hloop_t* loop) {
- return loop->start_time + (loop->cur_hrtime - loop->start_hrtime) / 1000000;
- }
- static inline uint64_t hloop_now_hrtime(hloop_t* loop) {
- return loop->start_time*1e6 + (loop->cur_hrtime - loop->start_hrtime);
- }
- // idle
- hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
- void hidle_del(hidle_t* idle);
- // timer
- // @param timeout: unit(ms)
- htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint64_t timeout, uint32_t repeat DEFAULT(INFINITE));
- /*
- * minute hour day week month cb
- * 0~59 0~23 1~31 0~6 1~12
- * 30 -1 -1 -1 -1 cron.hourly
- * 30 1 -1 -1 -1 cron.daily
- * 30 1 15 -1 -1 cron.monthly
- * 30 1 -1 7 -1 cron.weekly
- * 30 1 1 -1 10 cron.yearly
- */
- htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
- int8_t minute DEFAULT(0), int8_t hour DEFAULT(-1), int8_t day DEFAULT(-1),
- int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
- void htimer_del(htimer_t* timer);
- void htimer_reset(htimer_t* timer);
- // io
- // low-level api
- #define READ_EVENT 0x0001
- #define WRITE_EVENT 0x0004
- #define ALL_EVENTS READ_EVENT|WRITE_EVENT
- hio_t* hio_get(hloop_t* loop, int fd);
- int hio_add(hio_t* io, hio_cb cb, int events DEFAULT(READ_EVENT));
- int hio_del(hio_t* io, int events DEFAULT(ALL_EVENTS));
- void hio_setlocaladdr(hio_t* io, struct sockaddr* addr, int addrlen);
- void hio_setpeeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
- // high-level api
- hio_t* hread (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
- hio_t* hwrite (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
- void hclose (hio_t* io);
- // tcp
- hio_t* haccept (hloop_t* loop, int listenfd, haccept_cb accept_cb);
- hio_t* hconnect (hloop_t* loop, int connfd, hconnect_cb connect_cb);
- hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
- hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
- // @tcp_server: socket -> bind -> listen -> haccept
- hio_t* create_tcp_server (hloop_t* loop, int port, haccept_cb accept_cb);
- // @tcp_client: resolver -> socket -> hio_get -> hio_setpeeraddr -> hconnect
- hio_t* create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb);
- // udp/ip
- // NOTE: recvfrom/sendto struct sockaddr* addr save in io->peeraddr
- hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
- hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
- // @udp_server: socket -> bind -> hio_get
- hio_t* create_udp_server(hloop_t* loop, int port);
- // @udp_client: resolver -> socket -> hio_get -> hio_setpeeraddr
- hio_t* create_udp_client(hloop_t* loop, const char* host, int port);
- END_EXTERN_C
- #endif // HW_LOOP_H_
|