aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-01-04 15:10:35 -0800
committerAlon Zakai <alonzakai@gmail.com>2013-01-04 15:10:35 -0800
commit1951a1c74302c6ef11991cca801ec00d75ec1cc8 (patch)
tree718acaaa982b9e2ff5b221014058eb173697296f
parent05be831d56dc8fac85fe5a3af57eee0b9e409040 (diff)
refactor socket code, ensure that each call to recv/recvmsg receives a single separate message
-rw-r--r--src/library.js66
1 files changed, 23 insertions, 43 deletions
diff --git a/src/library.js b/src/library.js
index d20667bb..9c011730 100644
--- a/src/library.js
+++ b/src/library.js
@@ -6828,30 +6828,14 @@ LibraryManager.library = {
info.socket = new WebSocket('ws://' + info.host + ':' + info.port, ['binary']);
info.socket.binaryType = 'arraybuffer';
info.buffer = new Uint8Array(Sockets.BUFFER_SIZE);
- info.bufferWrite = info.bufferRead = 0;
- info.socket.onmessage = function (event) {
+ info.inQueue = [];
+ info.socket.onmessage = function(event) {
assert(typeof event.data !== 'string' && event.data.byteLength); // must get binary data!
var data = new Uint8Array(event.data); // make a typed array view on the array buffer
- var len = data.length;
#if SOCKET_DEBUG
- Module.print(['onmessage', window.location, data, len, '|', Array.prototype.slice.call(data)]);
+ Module.print(['onmessage', data.length, '|', Array.prototype.slice.call(data)]);
#endif
- for (var i = 0; i < len; i++) { // TODO: typed array set, carefully with ranges, or other trick
- info.buffer[info.bufferWrite++] = data[i];
- if (info.bufferWrite == info.buffer.length) info.bufferWrite = 0;
- if (info.bufferWrite == info.bufferRead) {
- // grow the buffer
- var currLen = info.buffer.length;
- if (currLen > Sockets.MAX_BUFFER_SIZE) throw 'socket buffer overflow';
- var newBuffer = new Uint8Array(currLen*2);
- for (var j = 0; j < currLen; j++) {
- newBuffer[j] = info.buffer[(info.bufferRead + j)%currLen];
- }
- info.bufferRead = 0;
- info.bufferWrite = currLen;
- info.buffer = newBuffer;
- }
- }
+ info.inQueue.push(data);
}
function send(data) {
// TODO: if browser accepts views, can optimize this
@@ -6891,25 +6875,19 @@ LibraryManager.library = {
recv: function(fd, buf, len, flags) {
var info = Sockets.fds[fd];
if (!info) return -1;
- if (info.bufferWrite == info.bufferRead) {
+ if (info.inQueue.length == 0) {
___setErrNo(ERRNO_CODES.EAGAIN); // no data, and all sockets are nonblocking, so this is the right behavior
return 0; // should this be -1 like the spec says?
}
- var ret = 0;
+ var buffer = info.inQueue.shift();
#if SOCKET_DEBUG
- Module.print('pre-recv: ' + [len, info.bufferWrite, info.bufferRead]);
+ Module.print('recv: ' + [Array.prototype.slice.call(buffer)]);
#endif
- while (info.bufferWrite != info.bufferRead && len > 0) {
- // write out a byte
- {{{ makeSetValue('buf++', '0', 'info.buffer[info.bufferRead++]', 'i8') }}};
- if (info.bufferRead == info.buffer.length) info.bufferRead = 0;
- len--;
- ret++;
+ if (len < buffer.length) {
+ buffer = buffer.subarray(0, len);
}
-#if SOCKET_DEBUG
- Module.print('recv: ' + [ret, len, buf] + ' : ' + Array.prototype.slice.call(HEAPU8.subarray(buf-ret, buf)));
-#endif
- return ret;
+ HEAPU8.set(buffer, buf);
+ return buffer.length;
},
send__deps: ['$Sockets'],
@@ -6968,12 +6946,12 @@ LibraryManager.library = {
assert(name, 'sendmsg on non-connected socket, and no name/address in the message');
_connect(fd, name, {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_namelen', 'i32') }}});
}
- var bytes = info.bufferWrite - info.bufferRead;
- if (bytes < 0) bytes += info.buffer.length;
- if (bytes == 0) {
+ if (info.inQueue.length == 0) {
___setErrNo(ERRNO_CODES.EWOULDBLOCK);
return -1;
}
+ var buffer = info.inQueue.shift();
+ var bytes = buffer.length;
#if SOCKET_DEBUG
Module.print('recvmsg bytes: ' + bytes);
#endif
@@ -6985,7 +6963,7 @@ LibraryManager.library = {
var ret = bytes;
var iov = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iov', 'i8*') }}};
var num = {{{ makeGetValue('msg', 'Sockets.msghdr_layout.msg_iovlen', 'i32') }}};
- var data = '';
+ var bufferPos = 0;
for (var i = 0; i < num && bytes > 0; i++) {
var currNum = {{{ makeGetValue('iov', '8*i + 4', 'i32') }}};
#if SOCKET_DEBUG
@@ -6998,7 +6976,8 @@ LibraryManager.library = {
#if SOCKET_DEBUG
Module.print('recvmsg call recv ' + currNum);
#endif
- assert(_recv(fd, currBuf, currNum, 0) == currNum);
+ HEAPU8.set(buffer.subarray(bufferPos, bufferPos + currNum), currBuf);
+ bufferPos += currNum;
}
return ret;
},
@@ -7025,11 +7004,12 @@ LibraryManager.library = {
ioctl: function(fd, request, varargs) {
var info = Sockets.fds[fd];
if (!info) return -1;
- var start = info.bufferRead;
- var end = info.bufferWrite;
- if (end < start) end += info.buffer.length;
+ var bytes = 0;
+ if (info.inQueue.length > 0) {
+ bytes = info.inQueue[0].length;
+ }
var dest = {{{ makeGetValue('varargs', '0', 'i32') }}};
- {{{ makeSetValue('dest', '0', 'end - start', 'i32') }}};
+ {{{ makeSetValue('dest', '0', 'bytes', 'i32') }}};
return 0;
},
@@ -7075,7 +7055,7 @@ LibraryManager.library = {
// index is in the set, check if it is ready for read
var info = Sockets.fds[fd];
if (!info) continue;
- if (info.bufferWrite != info.bufferRead) ret++;
+ if (info.inQueue.length > 0) ret++;
}
}
return ret;