Skip to content

Commit 1951a1c

Browse files
committed
refactor socket code, ensure that each call to recv/recvmsg receives a single separate message
1 parent 05be831 commit 1951a1c

1 file changed

Lines changed: 23 additions & 43 deletions

File tree

src/library.js

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6828,30 +6828,14 @@ LibraryManager.library = {
68286828
info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['binary']);
68296829
info.socket.binaryType = 'arraybuffer';
68306830
info.buffer = new Uint8Array(Sockets.BUFFER_SIZE);
6831-
info.bufferWrite = info.bufferRead = 0;
6832-
info.socket.onmessage = function (event) {
6831+
info.inQueue = [];
6832+
info.socket.onmessage = function(event) {
68336833
assert(typeof event.data !== 'string' && event.data.byteLength); // must get binary data!
68346834
var data = new Uint8Array(event.data); // make a typed array view on the array buffer
6835-
var len = data.length;
68366835
#if SOCKET_DEBUG
6837-
Module.print(['onmessage', window.location, data, len, '|', Array.prototype.slice.call(data)]);
6836+
Module.print(['onmessage', data.length, '|', Array.prototype.slice.call(data)]);
68386837
#endif
6839-
for (var i = 0; i < len; i++) { // TODO: typed array set, carefully with ranges, or other trick
6840-
info.buffer[info.bufferWrite++] = data[i];
6841-
if (info.bufferWrite == info.buffer.length) info.bufferWrite = 0;
6842-
if (info.bufferWrite == info.bufferRead) {
6843-
// grow the buffer
6844-
var currLen = info.buffer.length;
6845-
if (currLen > Sockets.MAX_BUFFER_SIZE) throw 'socket buffer overflow';
6846-
var newBuffer = new Uint8Array(currLen*2);
6847-
for (var j = 0; j < currLen; j++) {
6848-
newBuffer[j] = info.buffer[(info.bufferRead + j)%currLen];
6849-
}
6850-
info.bufferRead = 0;
6851-
info.bufferWrite = currLen;
6852-
info.buffer = newBuffer;
6853-
}
6854-
}
6838+
info.inQueue.push(data);
68556839
}
68566840
function send(data) {
68576841
// TODO: if browser accepts views, can optimize this
@@ -6891,25 +6875,19 @@ LibraryManager.library = {
68916875
recv: function(fd, buf, len, flags) {
68926876
var info = Sockets.fds[fd];
68936877
if (!info) return -1;
6894-
if (info.bufferWrite == info.bufferRead) {
6878+
if (info.inQueue.length == 0) {
68956879
___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior
68966880
return 0; // should this be -1 like the spec says?
68976881
}
6898-
var ret = 0;
6882+
var buffer = info.inQueue.shift();
68996883
#if SOCKET_DEBUG
6900-
Module.print('pre-recv: ' + [len, info.bufferWrite, info.bufferRead]);
6884+
Module.print('recv: ' + [Array.prototype.slice.call(buffer)]);
69016885
#endif
6902-
while (info.bufferWrite != info.bufferRead && len > 0) {
6903-
// write out a byte
6904-
{{{ makeSetValue('buf++', '0', 'info.buffer[info.bufferRead++]', 'i8') }}};
6905-
if (info.bufferRead == info.buffer.length) info.bufferRead = 0;
6906-
len--;
6907-
ret++;
6886+
if (len < buffer.length) {
6887+
buffer = buffer.subarray(0, len);
69086888
}
6909-
#if SOCKET_DEBUG
6910-
Module.print('recv: ' + [ret, len, buf] + ' : ' + Array.prototype.slice.call(HEAPU8.subarray(buf-ret, buf)));
6911-
#endif
6912-
return ret;
6889+
HEAPU8.set(buffer, buf);
6890+
return buffer.length;
69136891
},
69146892

69156893
send__deps: ['$Sockets'],
@@ -6968,12 +6946,12 @@ LibraryManager.library = {
69686946
assert(name, 'sendmsg on non-connected socket, and no name/address in the message');
69696947
_connect(fd, name, {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_namelen', 'i32') }}});
69706948
}
6971-
var bytes = info.bufferWrite - info.bufferRead;
6972-
if (bytes < 0) bytes += info.buffer.length;
6973-
if (bytes == 0) {
6949+
if (info.inQueue.length == 0) {
69746950
___setErrNo(ERRNO_CODES.EWOULDBLOCK);
69756951
return -1;
69766952
}
6953+
var buffer = info.inQueue.shift();
6954+
var bytes = buffer.length;
69776955
#if SOCKET_DEBUG
69786956
Module.print('recvmsg bytes: ' + bytes);
69796957
#endif
@@ -6985,7 +6963,7 @@ LibraryManager.library = {
69856963
var ret = bytes;
69866964
var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}};
69876965
var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
6988-
var data = '';
6966+
var bufferPos = 0;
69896967
for (var i = 0; i < num && bytes > 0; i++) {
69906968
var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}};
69916969
#if SOCKET_DEBUG
@@ -6998,7 +6976,8 @@ LibraryManager.library = {
69986976
#if SOCKET_DEBUG
69996977
Module.print('recvmsg call recv ' + currNum);
70006978
#endif
7001-
assert(_recv(fd, currBuf, currNum, 0) == currNum);
6979+
HEAPU8.set(buffer.subarray(bufferPos, bufferPos + currNum), currBuf);
6980+
bufferPos += currNum;
70026981
}
70036982
return ret;
70046983
},
@@ -7025,11 +7004,12 @@ LibraryManager.library = {
70257004
ioctl: function(fd, request, varargs) {
70267005
var info = Sockets.fds[fd];
70277006
if (!info) return -1;
7028-
var start = info.bufferRead;
7029-
var end = info.bufferWrite;
7030-
if (end < start) end += info.buffer.length;
7007+
var bytes = 0;
7008+
if (info.inQueue.length > 0) {
7009+
bytes = info.inQueue[0].length;
7010+
}
70317011
var dest = {{{ makeGetValue('varargs', '0', 'i32') }}};
7032-
{{{ makeSetValue('dest', '0', 'end - start', 'i32') }}};
7012+
{{{ makeSetValue('dest', '0', 'bytes', 'i32') }}};
70337013
return 0;
70347014
},
70357015

@@ -7075,7 +7055,7 @@ LibraryManager.library = {
70757055
// index is in the set, check if it is ready for read
70767056
var info = Sockets.fds[fd];
70777057
if (!info) continue;
7078-
if (info.bufferWrite != info.bufferRead) ret++;
7058+
if (info.inQueue.length > 0) ret++;
70797059
}
70807060
}
70817061
return ret;

0 commit comments

Comments
 (0)