/*
- * this function is called on a write event from a client socket.
+ * this function is called on a write event from a stream socket.
* It returns 0.
*/
-int event_cli_write(int fd) {
- struct task *t = fdtab[fd].owner;
+int stream_sock_write(int fd) {
struct buffer *b = fdtab[fd].cb[DIR_WR].b;
int ret, max;
#ifdef DEBUG_FULL
- fprintf(stderr,"event_cli_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
+ fprintf(stderr,"stream_sock_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
#endif
if (b->l == 0) { /* let's realign the buffer to optimize I/O */
b->r = b->w = b->h = b->lr = b->data;
- // max = BUFSIZE; BUG !!!!
max = 0;
}
else if (b->r > b->w) {
if (fdtab[fd].state != FD_STERROR) {
if (max == 0) {
+ /* may be we have received a connection acknowledgement in TCP mode without data */
+ if (fdtab[fd].state == FD_STCONN) {
+ int skerr;
+ socklen_t lskerr = sizeof(skerr);
+ getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
+ if (skerr) {
+ b->flags |= BF_WRITE_ERROR;
+ fdtab[fd].state = FD_STERROR;
+ task_wakeup(&rq, fdtab[fd].owner);
+ tv_eternity(&b->wex);
+ FD_CLR(fd, StaticWriteEvent);
+ return 0;
+ }
+ }
+
b->flags |= BF_WRITE_NULL;
- task_wakeup(&rq, t);
+ task_wakeup(&rq, fdtab[fd].owner);
+ fdtab[fd].state = FD_STREADY;
tv_eternity(&b->wex);
FD_CLR(fd, StaticWriteEvent);
return 0;
}
}
else if (ret == 0) {
- /* nothing written, just make as if we were never called */
+ /* nothing written, just pretend we were never called */
// b->flags |= BF_WRITE_NULL;
return 0;
}
else
tv_eternity(&b->wex);
- task_wakeup(&rq, t);
+ task_wakeup(&rq, fdtab[fd].owner);
return 0;
}
-
-/*
- * this function is called on a write event from a server socket.
- * It returns 0.
- */
-int event_srv_write(int fd) {
- struct task *t = fdtab[fd].owner;
- struct buffer *b = fdtab[fd].cb[DIR_WR].b;
- struct session *s = t->context;
- int ret, max;
-
-#ifdef DEBUG_FULL
- fprintf(stderr,"event_srv_write : fd=%d, s=%p\n", fd, s);
-#endif
-
- if (b->l == 0) { /* let's realign the buffer to optimize I/O */
- b->r = b->w = b->h = b->lr = b->data;
- // max = BUFSIZE; BUG !!!!
- max = 0;
- }
- else if (b->r > b->w) {
- max = b->r - b->w;
- }
- else
- max = b->data + BUFSIZE - b->w;
-
- if (fdtab[fd].state != FD_STERROR) {
- if (max == 0) {
- /* may be we have received a connection acknowledgement in TCP mode without data */
- if (s->srv_state == SV_STCONN) {
- int skerr;
- socklen_t lskerr = sizeof(skerr);
- getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
- if (skerr) {
- b->flags |= BF_WRITE_ERROR;
- fdtab[fd].state = FD_STERROR;
- task_wakeup(&rq, t);
- tv_eternity(&b->wex);
- FD_CLR(fd, StaticWriteEvent);
- return 0;
- }
- }
-
- b->flags |= BF_WRITE_NULL;
- task_wakeup(&rq, t);
- fdtab[fd].state = FD_STREADY;
- tv_eternity(&b->wex);
- FD_CLR(fd, StaticWriteEvent);
- return 0;
- }
-
-#ifndef MSG_NOSIGNAL
- {
- int skerr;
- socklen_t lskerr = sizeof(skerr);
- getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
- if (skerr)
- ret = -1;
- else
- ret = send(fd, b->w, max, MSG_DONTWAIT);
- }
-#else
- ret = send(fd, b->w, max, MSG_DONTWAIT | MSG_NOSIGNAL);
-#endif
- fdtab[fd].state = FD_STREADY;
- if (ret > 0) {
- b->l -= ret;
- b->w += ret;
-
- b->flags |= BF_PARTIAL_WRITE;
-
- if (b->w == b->data + BUFSIZE) {
- b->w = b->data; /* wrap around the buffer */
- }
- }
- else if (ret == 0) {
- /* nothing written, just make as if we were never called */
- // b->flags |= BF_WRITE_NULL;
- return 0;
- }
- else if (errno == EAGAIN) /* ignore EAGAIN */
- return 0;
- else {
- b->flags |= BF_WRITE_ERROR;
- fdtab[fd].state = FD_STERROR;
- }
- }
- else {
- b->flags |= BF_WRITE_ERROR;
- fdtab[fd].state = FD_STERROR;
- }
-
- /* We don't want to re-arm read/write timeouts if we're trying to connect,
- * otherwise it could loop indefinitely !
- */
- if (s->srv_state != SV_STCONN) {
- if (b->wto) {
- tv_delayfrom(&b->wex, &now, b->wto);
- /* FIXME: to prevent the client from expiring read timeouts during writes,
- * we refresh it. A solution would be to merge read+write timeouts into a
- * unique one, although that needs some study particularly on full-duplex
- * TCP connections. */
- b->rex = b->wex;
- }
- else
- tv_eternity(&b->wex);
- }
-
- task_wakeup(&rq, t);
- return 0;
-}
-
-
/*
* Local variables:
* c-indent-level: 8