5#include <winpr/handle.h>
6#include <winpr/sysinfo.h>
7#include <winpr/assert.h>
10#define TAG WINPR_TAG("sync.pollset")
12#if defined(__EMSCRIPTEN__)
15extern void winpr_pollset_js_yield(
void);
18#ifdef WINPR_HAVE_POLL_H
19static INT16 handle_mode_to_pollevent(ULONG mode)
23 if (mode & WINPR_FD_READ)
26 if (mode & WINPR_FD_WRITE)
33BOOL pollset_init(WINPR_POLL_SET* set,
size_t nhandles)
36#ifdef WINPR_HAVE_POLL_H
37 if (nhandles > MAXIMUM_WAIT_OBJECTS)
39 set->isStatic = FALSE;
40 set->pollset = calloc(nhandles,
sizeof(*set->pollset));
46 set->pollset = set->staticSet;
50 set->fdIndex = calloc(nhandles,
sizeof(*set->fdIndex));
54 FD_ZERO(&set->rset_base);
56 FD_ZERO(&set->wset_base);
59 set->nread = set->nwrite = 0;
67void pollset_uninit(WINPR_POLL_SET* set)
70#ifdef WINPR_HAVE_POLL_H
78void pollset_reset(WINPR_POLL_SET* set)
81#ifndef WINPR_HAVE_POLL_H
82 FD_ZERO(&set->rset_base);
83 FD_ZERO(&set->wset_base);
85 set->nread = set->nwrite = 0;
90BOOL pollset_add(WINPR_POLL_SET* set,
int fd, ULONG mode)
93#ifdef WINPR_HAVE_POLL_H
94 struct pollfd* item =
nullptr;
95 if (set->fillIndex == set->size)
98 item = &set->pollset[set->fillIndex];
101 item->events = handle_mode_to_pollevent(mode);
103 FdIndex* fdIndex = &set->fdIndex[set->fillIndex];
104 if (mode & WINPR_FD_READ)
106 FD_SET(fd, &set->rset_base);
110 if (mode & WINPR_FD_WRITE)
112 FD_SET(fd, &set->wset_base);
120 fdIndex->mode = mode;
126int pollset_poll(WINPR_POLL_SET* set, DWORD dwMilliseconds)
133 now = GetTickCount64();
134 if (dwMilliseconds == INFINITE)
135 dueTime = 0xFFFFFFFFFFFFFFFF;
137 dueTime = now + dwMilliseconds;
139#ifdef WINPR_HAVE_POLL_H
144 if (dwMilliseconds == INFINITE)
147 timeout = (int)(dueTime - now);
149 ret = poll(set->pollset, WINPR_ASSERTING_INT_CAST(nfds_t, set->fillIndex), timeout);
152#if defined(__EMSCRIPTEN__)
157 if (++set->yieldCounter > 10)
159 winpr_pollset_js_yield();
160 set->yieldCounter = 0;
164 set->yieldCounter = 0;
172 now = GetTickCount64();
173 }
while (now < dueTime);
178 struct timeval staticTimeout;
179 struct timeval* timeout;
181 fd_set* rset =
nullptr;
182 fd_set* wset =
nullptr;
184 if (dwMilliseconds == INFINITE)
190 long waitTime = (long)(dueTime - now);
192 timeout = &staticTimeout;
193 timeout->tv_sec = waitTime / 1000;
194 timeout->tv_usec = (waitTime % 1000) * 1000;
200 memcpy(rset, &set->rset_base,
sizeof(*rset));
206 memcpy(wset, &set->wset_base,
sizeof(*wset));
209 ret = select(set->maxFd + 1, rset, wset,
nullptr, timeout);
216 now = GetTickCount64();
218 }
while (now < dueTime);
227BOOL pollset_isSignaled(WINPR_POLL_SET* set,
size_t idx)
231 if (idx > set->fillIndex)
233 WLog_ERR(TAG,
"index=%" PRIuz
" out of pollset(fillIndex=%" PRIuz
")", idx, set->fillIndex);
237#ifdef WINPR_HAVE_POLL_H
238 return !!(set->pollset[idx].revents & set->pollset[idx].events);
240 FdIndex* fdIndex = &set->fdIndex[idx];
244 if ((fdIndex->mode & WINPR_FD_READ) && FD_ISSET(fdIndex->fd, &set->rset))
247 if ((fdIndex->mode & WINPR_FD_WRITE) && FD_ISSET(fdIndex->fd, &set->wset))
254BOOL pollset_isReadSignaled(WINPR_POLL_SET* set,
size_t idx)
258 if (idx > set->fillIndex)
260 WLog_ERR(TAG,
"index=%" PRIuz
" out of pollset(fillIndex=%" PRIuz
")", idx, set->fillIndex);
264#ifdef WINPR_HAVE_POLL_H
265 return !!(set->pollset[idx].revents & POLLIN);
267 FdIndex* fdIndex = &set->fdIndex[idx];
271 return FD_ISSET(fdIndex->fd, &set->rset);
275BOOL pollset_isWriteSignaled(WINPR_POLL_SET* set,
size_t idx)
279 if (idx > set->fillIndex)
281 WLog_ERR(TAG,
"index=%" PRIuz
" out of pollset(fillIndex=%" PRIuz
")", idx, set->fillIndex);
285#ifdef WINPR_HAVE_POLL_H
286 return !!(set->pollset[idx].revents & POLLOUT);
288 FdIndex* fdIndex = &set->fdIndex[idx];
292 return FD_ISSET(fdIndex->fd, &set->wset);