Skip to content

Commit ac3f5b7

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

File tree

1 file changed

+80
-54
lines changed

1 file changed

+80
-54
lines changed

src/lib/libsyscall.js

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,73 @@ 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+
allLow: srcReadLow | srcWriteLow | srcExceptLow,
138+
allHigh: srcReadHigh | srcWriteHigh | srcExceptHigh,
139+
getTotal: () => total,
140+
setFlags: (fd, flags) => {
141+
var mask = 1 << (fd % 32);
142+
143+
if ((flags & {{{ cDefs.POLLIN }}}) && check(fd, srcReadLow, srcReadHigh, mask)) {
144+
fd < 32 ? (dstReadLow = dstReadLow | mask) : (dstReadHigh = dstReadHigh | mask);
145+
total++;
146+
}
147+
if ((flags & {{{ cDefs.POLLOUT }}}) && check(fd, srcWriteLow, srcWriteHigh, mask)) {
148+
fd < 32 ? (dstWriteLow = dstWriteLow | mask) : (dstWriteHigh = dstWriteHigh | mask);
149+
total++;
150+
}
151+
if ((flags & {{{ cDefs.POLLPRI }}}) && check(fd, srcExceptLow, srcExceptHigh, mask)) {
152+
fd < 32 ? (dstExceptLow = dstExceptLow | mask) : (dstExceptHigh = dstExceptHigh | mask);
153+
total++;
154+
}
155+
},
156+
commit: () => {
157+
if (readfds) {
158+
{{{ makeSetValue('readfds', '0', 'dstReadLow', 'i32') }}};
159+
{{{ makeSetValue('readfds', '4', 'dstReadHigh', 'i32') }}};
160+
}
161+
if (writefds) {
162+
{{{ makeSetValue('writefds', '0', 'dstWriteLow', 'i32') }}};
163+
{{{ makeSetValue('writefds', '4', 'dstWriteHigh', 'i32') }}};
164+
}
165+
if (exceptfds) {
166+
{{{ makeSetValue('exceptfds', '0', 'dstExceptLow', 'i32') }}};
167+
{{{ makeSetValue('exceptfds', '4', 'dstExceptHigh', 'i32') }}};
168+
}
169+
}
170+
};
171+
},
105172
},
106173

107174
$syscallGetVarargI__internal: true,
@@ -552,27 +619,18 @@ var SyscallsLibrary = {
552619
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
553620
#endif
554621

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;
622+
var fdSet = SYSCALLS.parseSelectFDSet(readfds, writefds, exceptfds);
570623

571-
var allLow = srcReadLow | srcWriteLow | srcExceptLow;
572-
var allHigh = srcReadHigh | srcWriteHigh | srcExceptHigh;
624+
var allLow = fdSet.allLow;
625+
var allHigh = fdSet.allHigh;
573626

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

629+
var timeoutInMillis = -1;
630+
if (timeout) {
631+
timeoutInMillis = SYSCALLS.getTimeoutInMillis(timeout);
632+
}
633+
576634
for (var fd = 0; fd < nfds; fd++) {
577635
var mask = 1 << (fd % 32);
578636
if (!(check(fd, allLow, allHigh, mask))) {
@@ -584,48 +642,16 @@ var SyscallsLibrary = {
584642
var flags = SYSCALLS.DEFAULT_POLLMASK;
585643

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

601-
if ((flags & {{{ cDefs.POLLIN }}}) && check(fd, srcReadLow, srcReadHigh, mask)) {
602-
fd < 32 ? (dstReadLow = dstReadLow | mask) : (dstReadHigh = dstReadHigh | mask);
603-
total++;
604-
}
605-
if ((flags & {{{ cDefs.POLLOUT }}}) && check(fd, srcWriteLow, srcWriteHigh, mask)) {
606-
fd < 32 ? (dstWriteLow = dstWriteLow | mask) : (dstWriteHigh = dstWriteHigh | mask);
607-
total++;
608-
}
609-
if ((flags & {{{ cDefs.POLLPRI }}}) && check(fd, srcExceptLow, srcExceptHigh, mask)) {
610-
fd < 32 ? (dstExceptLow = dstExceptLow | mask) : (dstExceptHigh = dstExceptHigh | mask);
611-
total++;
612-
}
648+
fdSet.setFlags(fd, flags);
613649
}
614650

615-
if (readfds) {
616-
{{{ makeSetValue('readfds', '0', 'dstReadLow', 'i32') }}};
617-
{{{ makeSetValue('readfds', '4', 'dstReadHigh', 'i32') }}};
618-
}
619-
if (writefds) {
620-
{{{ makeSetValue('writefds', '0', 'dstWriteLow', 'i32') }}};
621-
{{{ makeSetValue('writefds', '4', 'dstWriteHigh', 'i32') }}};
622-
}
623-
if (exceptfds) {
624-
{{{ makeSetValue('exceptfds', '0', 'dstExceptLow', 'i32') }}};
625-
{{{ makeSetValue('exceptfds', '4', 'dstExceptHigh', 'i32') }}};
626-
}
627651

628-
return total;
652+
fdSet.commit();
653+
654+
return fdSet.getTotal();
629655
},
630656
_msync_js__i53abi: true,
631657
_msync_js: (addr, len, prot, flags, fd, offset) => {

0 commit comments

Comments
 (0)