Go to the documentation of this file.
22 #ifdef HAVE_SYS_SELECT_H
23 # include <sys/select.h>
26 #define WM_MIO_EVENT (WM_APP + 100)
29 static ATOM mio_class = NULL; \
31 LONG CALLBACK _mio_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LONG lParam); \
33 static mio_fd_t _mio_alloc_fd(mio_t m, int fd) \
35 mio_priv_fd_t priv_fd = MIO(m)->next_free; \
40 MIO(m)->next_free = priv_fd->next_free; \
41 priv_fd->mio_fd.fd = fd; \
42 priv_fd->next_free = NULL; \
44 return (mio_fd_t)priv_fd; \
47 static void _mio_free_fd(mio_t m, mio_priv_fd_t priv_fd) \
49 priv_fd->next_free = MIO(m)->next_free; \
50 priv_fd->mio_fd.fd = 0; \
51 priv_fd->revent = 0; \
53 MIO(m)->next_free = priv_fd; \
56 static int _mio_select(mio_priv_t m, int t) \
58 MSG msg; int lResult = 0; \
59 MIO(m)->select_fd = NULL; \
60 MIO(m)->timer = SetTimer(MIO(m)->hwnd, \
61 MIO(m)->timer ? MIO(m)->timer : 0, 1000 * t, NULL); \
62 while(!lResult && GetMessage(&msg, NULL, 0, 0)) \
64 TranslateMessage(&msg); \
65 lResult = DispatchMessage(&msg); \
67 return MIO(m)->select_fd ? 1 : 0; \
70 static mio_priv_fd_t _mio_peek(mio_priv_t m) \
73 MIO(m)->select_fd = NULL; \
74 if(PeekMessage(&msg, MIO(m)->hwnd, WM_MIO_EVENT, WM_MIO_EVENT + MIO(m)->maxfd, PM_REMOVE)) \
76 TranslateMessage(&msg); \
77 DispatchMessage(&msg); \
79 return MIO(m)->select_fd; \
83 struct mio_priv_fd_st *next_free; \
93 mio_priv_fd_t select_fd; \
95 mio_priv_fd_t next_free;
97 #define MIO_INIT_VARS(m) \
100 HINSTANCE hInstance = GetModuleHandle(NULL); \
101 MIO(m)->defer_free = 0; \
102 if(mio_class == NULL) { \
104 memset(&wndclass, 0, sizeof(WNDCLASS)); \
105 wndclass.style = CS_NOCLOSE; \
106 wndclass.lpfnWndProc = _mio_wnd_proc; \
107 wndclass.lpszClassName = "jabberd2mio"; \
108 wndclass.hInstance = hInstance; \
110 if((mio_class = RegisterClass(&wndclass)) == NULL) { \
111 mio_debug(ZONE, "cannot create listener class (%d, %x)", GetLastError(), hInstance); \
115 mio_debug(ZONE, "created listener class"); \
117 MIO(m)->hwnd = CreateWindow("jabberd2mio", "jabberd2mio", \
118 0, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, \
119 NULL, NULL, hInstance, m); \
120 if(MIO(m)->hwnd == NULL) { \
121 mio_debug(ZONE, "cannot create listener window (%d, %x)", GetLastError(), hInstance); \
125 mio_debug(ZONE, "created listener window (%x)", MIO(m)->hwnd); \
126 if((MIO(m)->fds = malloc(sizeof(struct mio_priv_fd_st) * maxfd)) == NULL) { \
127 mio_debug(ZONE, "cannot allocate descriptors table"); \
131 memset(MIO(m)->fds, 0, sizeof(struct mio_priv_fd_st) * maxfd); \
132 MIO(m)->count = maxfd; \
133 for(i = 0; i < maxfd; i++) \
134 MIO(m)->fds[i].idx = i; \
135 for(i = 0; i < maxfd - 1; i++) \
136 MIO(m)->fds[i].next_free = &(MIO(m)->fds[i + 1]); \
137 MIO(m)->fds[maxfd - 1].next_free = NULL; \
138 MIO(m)->next_free = &(MIO(m)->fds[0]); \
139 MIO(m)->select_fd = NULL; \
142 #define MIO_FREE_VARS(m) \
144 DestroyWindow(MIO(m)->hwnd); \
148 #define MIO_ALLOC_FD(m, rfd) _mio_alloc_fd(MIO(m), rfd)
149 #define MIO_FREE_FD(m, mfd) _mio_free_fd(m, mfd)
151 #define MIO_DEQUEUE(m, mfd) \
154 WSAAsyncSelect(mfd->mio_fd.fd, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, 0); \
155 while(PeekMessage(&msg, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, WM_MIO_EVENT + mfd->idx, PM_REMOVE)); \
158 #define MIO_REMOVE_FD(m, mfd) MIO_DEQUEUE(m, mfd)
160 #define MIO_CHECK(m, t) _mio_select(m, t)
162 #define MIO_SET_READ(m, mfd) \
163 if(!(mfd->event & FD_READ)) { \
164 MIO_DEQUEUE(m, mfd); \
165 WSAAsyncSelect(mfd->mio_fd.fd, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, (mfd->event |= FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE)); \
167 #define MIO_SET_WRITE(m, mfd) \
168 if(!(mfd->event & FD_WRITE)) { \
169 MIO_DEQUEUE(m, mfd); \
170 WSAAsyncSelect(mfd->mio_fd.fd, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, (mfd->event |= FD_WRITE|FD_CONNECT|FD_CLOSE)); \
173 #define MIO_UNSET_READ(m, mfd) \
174 if(mfd->event & FD_READ) { \
175 mfd->event &= ~(FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE); \
176 if(mfd->event & FD_WRITE) \
177 mfd->event = FD_WRITE|FD_CONNECT|FD_CLOSE; \
178 MIO_DEQUEUE(m, mfd); \
179 WSAAsyncSelect(mfd->mio_fd.fd, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, mfd->event); \
181 #define MIO_UNSET_WRITE(m, mfd) \
182 if(mfd->event & FD_WRITE) { \
183 mfd->event &= ~FD_WRITE; \
184 if(!(mfd->event & FD_READ)) \
186 MIO_DEQUEUE(m, mfd); \
187 WSAAsyncSelect(mfd->mio_fd.fd, MIO(m)->hwnd, WM_MIO_EVENT + mfd->idx, mfd->event); \
190 #define MIO_CAN_READ(m, iter) (iter->revent & (FD_READ|FD_ACCEPT|FD_CONNECT|FD_CLOSE))
191 #define MIO_CAN_WRITE(m, iter) ((iter->revent & FD_WRITE) || !(iter->revent & FD_READ) && (iter->revent & (FD_CONNECT|FD_CLOSE)))
192 #define MIO_CAN_FREE(m) (!MIO(m)->defer_free)
194 #define MIO_INIT_ITERATOR(iter) \
195 mio_priv_fd_t iter = NULL
197 #define MIO_ITERATE_RESULTS(m, retval, iter) \
198 for(MIO(m)->defer_free = 1, iter = MIO(m)->select_fd; iter || ((MIO(m)->defer_free = 0)); iter = _mio_peek(m))
200 #define MIO_ITERATOR_FD(m, iter) \