summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-11-28 11:13:27 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2017-11-29 18:20:23 +0100
commit0891ef4826e347d5554c630b5c0ce73c68f76c9c (patch)
tree709e83f364bc7950d2716f65b513384a9d335ef7
parent45c8372c2b4137691a38c2a04f4a5759a110f2f7 (diff)
afb-ws & websocket: Fix writing very long data
This version loops to write very long data on websockets. Bug-AGL: SPEC-1091 Change-Id: I8f17e75e4ef483be29fa8cae2c0af159783ec2c6 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-apiset.c1
-rw-r--r--src/afb-ws.c57
-rw-r--r--src/websock.c10
3 files changed, 47 insertions, 21 deletions
diff --git a/src/afb-apiset.c b/src/afb-apiset.c
index cad12e97..ae1d9460 100644
--- a/src/afb-apiset.c
+++ b/src/afb-apiset.c
@@ -29,7 +29,6 @@
#include "afb-apiset.h"
#include "afb-context.h"
#include "afb-xreq.h"
-#include "jobs.h"
#define INCR 8 /* CAUTION: must be a power of 2 */
diff --git a/src/afb-ws.c b/src/afb-ws.c
index ff625fca..c48a5e24 100644
--- a/src/afb-ws.c
+++ b/src/afb-ws.c
@@ -347,21 +347,58 @@ int afb_ws_binary_v(struct afb_ws *ws, const struct iovec *iovec, int count)
*/
static ssize_t aws_writev(struct afb_ws *ws, const struct iovec *iov, int iovcnt)
{
- ssize_t rc;
+ int i;
+ ssize_t rc, sz, dsz;
+ struct iovec *iov2;
+ struct pollfd pfd;
+
+ /* compute the size */
+ dsz = 0;
+ i = 0;
+ while (i < iovcnt) {
+ dsz += iov[i++].iov_len;
+ if (dsz < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ if (dsz == 0)
+ return 0;
+
+ /* write the data */
+ iov2 = (struct iovec*)iov;
+ sz = dsz;
for (;;) {
- rc = writev(ws->fd, iov, iovcnt);
- if (rc == -1) {
+ rc = writev(ws->fd, iov2, iovcnt);
+ if (rc < 0) {
if (errno == EINTR)
continue;
- else if (errno == EAGAIN) {
- struct pollfd pfd;
- pfd.fd = ws->fd;
- pfd.events = POLLOUT;
- poll(&pfd, 1, 10);
- continue;
+ if (errno != EAGAIN)
+ return -1;
+ } else {
+ dsz -= rc;
+ if (dsz == 0)
+ return sz;
+
+ i = 0;
+ while (rc >= (ssize_t)iov2[i].iov_len)
+ rc -= (ssize_t)iov2[i++].iov_len;
+
+ iovcnt -= i;
+ if (iov2 != iov)
+ iov2 += i;
+ else {
+ iov += i;
+ iov2 = alloca(iovcnt * sizeof *iov2);
+ for (i = 0 ; i < iovcnt ; i++)
+ iov2[i] = iov[i];
}
+ iov2->iov_base += rc;
+ iov2->iov_len -= rc;
}
- return rc;
+ pfd.fd = ws->fd;
+ pfd.events = POLLOUT;
+ poll(&pfd, 1, 10);
}
}
diff --git a/src/websock.c b/src/websock.c
index cc1e191e..84a11d78 100644
--- a/src/websock.c
+++ b/src/websock.c
@@ -84,16 +84,6 @@ static ssize_t ws_readv(struct websock *ws, const struct iovec *iov, int iovcnt)
return ws->itf->readv(ws->closure, iov, iovcnt);
}
-#if 0
-static ssize_t ws_write(struct websock *ws, const void *buffer, size_t buffer_size)
-{
- struct iovec iov;
- iov.iov_base = (void *)buffer; /* const cast */
- iov.iov_len = buffer_size;
- return ws_writev(ws, &iov, 1);
-}
-#endif
-
static ssize_t ws_read(struct websock *ws, void *buffer, size_t buffer_size)
{
struct iovec iov;