Skip to content

Commit 85251d5

Browse files
committed
select: separate parsers to functions
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
1 parent 8ac7ef7 commit 85251d5

File tree

1 file changed

+76
-52
lines changed

1 file changed

+76
-52
lines changed

src/lib/libsyscall.js

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,71 @@ var SyscallsLibrary = {
102102
#endif
103103
return ret;
104104
},
105+
106+
getTimeoutInMillis(timeout) {
107+
// select(2) is declared to accept "struct timeval { time_t tv_sec; suseconds_t tv_usec; }".
108+
// However, musl passes the two values to the syscall as an array of long values.
109+
// Note that sizeof(time_t) != sizeof(long) in wasm32. The former is 8, while the latter is 4.
110+
// This means using "C_STRUCTS.timeval.tv_usec" leads to a wrong offset.
111+
// So, instead, we use POINTER_SIZE.
112+
var tv_sec = ({{{ makeGetValue('timeout', 0, 'i32') }}}),
113+
tv_usec = ({{{ makeGetValue('timeout', POINTER_SIZE, 'i32') }}});
114+
return (tv_sec + tv_usec / 1000000) * 1000;
115+
},
116+
117+
parseSelectFDSet(readfds, writefds, exceptfds) {
118+
var total = 0;
119+
120+
var srcReadLow = (readfds ? {{{ makeGetValue('readfds', 0, 'i32') }}} : 0),
121+
srcReadHigh = (readfds ? {{{ makeGetValue('readfds', 4, 'i32') }}} : 0);
122+
var srcWriteLow = (writefds ? {{{ makeGetValue('writefds', 0, 'i32') }}} : 0),
123+
srcWriteHigh = (writefds ? {{{ makeGetValue('writefds', 4, 'i32') }}} : 0);
124+
var srcExceptLow = (exceptfds ? {{{ makeGetValue('exceptfds', 0, 'i32') }}} : 0),
125+
srcExceptHigh = (exceptfds ? {{{ makeGetValue('exceptfds', 4, 'i32') }}} : 0);
126+
127+
var dstReadLow = 0,
128+
dstReadHigh = 0;
129+
var dstWriteLow = 0,
130+
dstWriteHigh = 0;
131+
var dstExceptLow = 0,
132+
dstExceptHigh = 0;
133+
134+
var check = (fd, low, high, val) => fd < 32 ? (low & val) : (high & val);
135+
136+
return {
137+
getTotal: () => total,
138+
setFlags: (fd, flags) => {
139+
var mask = 1 << (fd % 32);
140+
141+
if ((flags & {{{ cDefs.POLLIN }}}) && check(fd, srcReadLow, srcReadHigh, mask)) {
142+
fd < 32 ? (dstReadLow = dstReadLow | mask) : (dstReadHigh = dstReadHigh | mask);
143+
total++;
144+
}
145+
if ((flags & {{{ cDefs.POLLOUT }}}) && check(fd, srcWriteLow, srcWriteHigh, mask)) {
146+
fd < 32 ? (dstWriteLow = dstWriteLow | mask) : (dstWriteHigh = dstWriteHigh | mask);
147+
total++;
148+
}
149+
if ((flags & {{{ cDefs.POLLPRI }}}) && check(fd, srcExceptLow, srcExceptHigh, mask)) {
150+
fd < 32 ? (dstExceptLow = dstExceptLow | mask) : (dstExceptHigh = dstExceptHigh | mask);
151+
total++;
152+
}
153+
},
154+
commit: () => {
155+
if (readfds) {
156+
{{{ makeSetValue('readfds', '0', 'dstReadLow', 'i32') }}};
157+
{{{ makeSetValue('readfds', '4', 'dstReadHigh', 'i32') }}};
158+
}
159+
if (writefds) {
160+
{{{ makeSetValue('writefds', '0', 'dstWriteLow', 'i32') }}};
161+
{{{ makeSetValue('writefds', '4', 'dstWriteHigh', 'i32') }}};
162+
}
163+
if (exceptfds) {
164+
{{{ makeSetValue('exceptfds', '0', 'dstExceptLow', 'i32') }}};
165+
{{{ makeSetValue('exceptfds', '4', 'dstExceptHigh', 'i32') }}};
166+
}
167+
}
168+
};
169+
},
105170
},
106171

107172
$syscallGetVarargI__internal: true,
@@ -552,21 +617,7 @@ var SyscallsLibrary = {
552617
assert(nfds <= 64, 'nfds must be less than or equal to 64'); // fd sets have 64 bits // TODO: this could be 1024 based on current musl headers
553618
#endif
554619

555-
var total = 0;
556-
557-
var srcReadLow = (readfds ? {{{ makeGetValue('readfds', 0, 'i32') }}} : 0),
558-
srcReadHigh = (readfds ? {{{ makeGetValue('readfds', 4, 'i32') }}} : 0);
559-
var srcWriteLow = (writefds ? {{{ makeGetValue('writefds', 0, 'i32') }}} : 0),
560-
srcWriteHigh = (writefds ? {{{ makeGetValue('writefds', 4, 'i32') }}} : 0);
561-
var srcExceptLow = (exceptfds ? {{{ makeGetValue('exceptfds', 0, 'i32') }}} : 0),
562-
srcExceptHigh = (exceptfds ? {{{ makeGetValue('exceptfds', 4, 'i32') }}} : 0);
563-
564-
var dstReadLow = 0,
565-
dstReadHigh = 0;
566-
var dstWriteLow = 0,
567-
dstWriteHigh = 0;
568-
var dstExceptLow = 0,
569-
dstExceptHigh = 0;
620+
var fdSet = SYSCALLS.parseSelectFDSet(readfds, writefds, exceptfds);
570621

571622
var allLow = (readfds ? {{{ makeGetValue('readfds', 0, 'i32') }}} : 0) |
572623
(writefds ? {{{ makeGetValue('writefds', 0, 'i32') }}} : 0) |
@@ -577,6 +628,11 @@ var SyscallsLibrary = {
577628

578629
var check = (fd, low, high, val) => fd < 32 ? (low & val) : (high & val);
579630

631+
var timeoutInMillis = -1;
632+
if (timeout) {
633+
timeoutInMillis = SYSCALLS.getTimeoutInMillis(timeout);
634+
}
635+
580636
for (var fd = 0; fd < nfds; fd++) {
581637
var mask = 1 << (fd % 32);
582638
if (!(check(fd, allLow, allHigh, mask))) {
@@ -588,48 +644,16 @@ var SyscallsLibrary = {
588644
var flags = SYSCALLS.DEFAULT_POLLMASK;
589645

590646
if (stream.stream_ops.poll) {
591-
var timeoutInMillis = -1;
592-
if (timeout) {
593-
// select(2) is declared to accept "struct timeval { time_t tv_sec; suseconds_t tv_usec; }".
594-
// However, musl passes the two values to the syscall as an array of long values.
595-
// Note that sizeof(time_t) != sizeof(long) in wasm32. The former is 8, while the latter is 4.
596-
// This means using "C_STRUCTS.timeval.tv_usec" leads to a wrong offset.
597-
// So, instead, we use POINTER_SIZE.
598-
var tv_sec = (readfds ? {{{ makeGetValue('timeout', 0, 'i32') }}} : 0),
599-
tv_usec = (readfds ? {{{ makeGetValue('timeout', POINTER_SIZE, 'i32') }}} : 0);
600-
timeoutInMillis = (tv_sec + tv_usec / 1000000) * 1000;
601-
}
602-
flags = stream.stream_ops.poll(stream, timeoutInMillis);
647+
flags = stream.stream_ops.poll(stream, ((timeoutInMillis < 0) || readfds) ? timeoutInMillis : 0);
603648
}
604649

605-
if ((flags & {{{ cDefs.POLLIN }}}) && check(fd, srcReadLow, srcReadHigh, mask)) {
606-
fd < 32 ? (dstReadLow = dstReadLow | mask) : (dstReadHigh = dstReadHigh | mask);
607-
total++;
608-
}
609-
if ((flags & {{{ cDefs.POLLOUT }}}) && check(fd, srcWriteLow, srcWriteHigh, mask)) {
610-
fd < 32 ? (dstWriteLow = dstWriteLow | mask) : (dstWriteHigh = dstWriteHigh | mask);
611-
total++;
612-
}
613-
if ((flags & {{{ cDefs.POLLPRI }}}) && check(fd, srcExceptLow, srcExceptHigh, mask)) {
614-
fd < 32 ? (dstExceptLow = dstExceptLow | mask) : (dstExceptHigh = dstExceptHigh | mask);
615-
total++;
616-
}
650+
fdSet.setFlags(fd, flags);
617651
}
618652

619-
if (readfds) {
620-
{{{ makeSetValue('readfds', '0', 'dstReadLow', 'i32') }}};
621-
{{{ makeSetValue('readfds', '4', 'dstReadHigh', 'i32') }}};
622-
}
623-
if (writefds) {
624-
{{{ makeSetValue('writefds', '0', 'dstWriteLow', 'i32') }}};
625-
{{{ makeSetValue('writefds', '4', 'dstWriteHigh', 'i32') }}};
626-
}
627-
if (exceptfds) {
628-
{{{ makeSetValue('exceptfds', '0', 'dstExceptLow', 'i32') }}};
629-
{{{ makeSetValue('exceptfds', '4', 'dstExceptHigh', 'i32') }}};
630-
}
631653

632-
return total;
654+
fdSet.commit(fd, flags);
655+
656+
return fdSet.getTotal();
633657
},
634658
_msync_js__i53abi: true,
635659
_msync_js: (addr, len, prot, flags, fd, offset) => {

0 commit comments

Comments
 (0)