1 2 3 #ifndef __LIBGSOCKET_SELECT_H__ 4 #define __LIBGSOCKET_SELECT_H__ 1 5 6 7 struct _gs_sel_item 8 { 9 int (*func)(void *ctx, int fd, void *cb_arg, int cb_val); 10 void *cb_arg; 11 int cb_val; 12 }; 13 14 enum bfunc_state {GS_CALLREAD = 0x01, GS_CALLWRITE = 0x02}; 15 typedef struct _gs_select_ctx 16 { 17 int max_fd; 18 fd_set *rfd; 19 fd_set *wfd; 20 fd_set *r; 21 fd_set *w; 22 struct timeval tv; 23 struct timeval *tv_now; 24 25 struct _gs_sel_item mgr_r[FD_SETSIZE]; 26 struct _gs_sel_item mgr_w[FD_SETSIZE]; 27 28 enum bfunc_state blocking_func[FD_SETSIZE]; 29 int saved_rw_state[FD_SETSIZE]; /* 0 == not saved. 1 = READ, 2 = WRITE, 3 = R&W */ 30 int is_rw_state_saved[FD_SETSIZE]; 31 int want_io_write[FD_SETSIZE]; 32 int want_io_read[FD_SETSIZE]; 33 34 int rdata_pending[FD_SETSIZE]; 35 int rdata_pending_count; 36 37 GS_EVENT_MGR emgr; // Event Manager (for Heartbeat) 38 GS_EVENT hb; // Heatbeat timeout; return control to caller 39 } GS_SELECT_CTX; 40 41 typedef int (*gselect_cb_t)(GS_SELECT_CTX *ctx, int fd, void *arg, int val); 42 43 int GS_SELECT_CTX_init(GS_SELECT_CTX *ctx, fd_set *rfd, fd_set *wfd, fd_set *r, fd_set *w, struct timeval *tv_now, int frequency); 44 int GS_select(GS_SELECT_CTX *ctx); 45 void GS_SELECT_add_cb_r(GS_SELECT_CTX *ctx, gselect_cb_t func, int fd, void *arg, int val); 46 void GS_SELECT_add_cb_w(GS_SELECT_CTX *ctx, gselect_cb_t func, int fd, void *arg, int val); 47 void GS_SELECT_add_cb(GS_SELECT_CTX *ctx, gselect_cb_t func_r, gselect_cb_t func_w, int fd, void *arg, int val); 48 void GS_SELECT_add_cb_callagain(GS_SELECT_CTX *ctx, gselect_cb_t func_r, gselect_cb_t func_w, int fd, void *arg, int val); 49 void GS_SELECT_del_cb(GS_SELECT_CTX *ctx, int fd); 50 void GS_SELECT_del_cb_callagain(GS_SELECT_CTX *ctx, int fd); 51 52 #define GS_SELECT_FD_CLR_R(ctx, fd) do { \ 53 if ((ctx)->is_rw_state_saved[fd]) { ctx->saved_rw_state[fd] &= ~0x01; } \ 54 FD_CLR(fd, (ctx)->rfd); \ 55 } while (0) 56 57 #define GS_SELECT_FD_CLR_W(ctx, fd) do { \ 58 if ((ctx)->is_rw_state_saved[fd]) { ctx->saved_rw_state[fd] &= ~0x02; } \ 59 FD_CLR(fd, (ctx)->wfd); \ 60 } while (0) 61 62 #define GS_SELECT_FD_SET_R(ctx, fd) do { \ 63 if ((ctx)->is_rw_state_saved[fd]) { \ 64 ctx->saved_rw_state[fd] |= 0x01; \ 65 } else { \ 66 XFD_SET(fd, (ctx)->rfd); \ 67 } \ 68 } while (0) 69 70 #define GS_SUCCESS (0x00) 71 #define GS_ECALLAGAIN (0x01) // Return Error Likes to be calleda gain 72 #define GS_ERR_WAITING -1 // Waiting for I/O 73 #define GS_ERR_FATAL -2 // must exit (?) 74 #define GS_ERR_EOF -3 75 #define GS_ERROR -4 76 77 #endif /* !__LIBGSOCKET_SELECT_H__ */ 78