Index: ossp-pkg/pth/pth_high.c RCS File: /v/ossp/cvs/ossp-pkg/pth/pth_high.c,v rcsdiff -q -kk '-r1.79' '-r1.80' -u '/v/ossp/cvs/ossp-pkg/pth/pth_high.c,v' 2>/dev/null --- pth_high.c 2001/07/30 18:47:28 1.79 +++ pth_high.c 2002/01/27 10:47:01 1.80 @@ -860,6 +860,9 @@ ssize_t rv; ssize_t s; int n; + struct iovec tiov_stack[32]; + struct iovec *tiov; + int tiovcnt; pth_implicit_init(); pth_debug2("pth_writev_ev: enter from thread \"%s\"", pth_current->name); @@ -873,6 +876,16 @@ /* poll filedescriptor if not already in non-blocking operation */ if (fdmode != PTH_FDMODE_NONBLOCK) { + /* provide temporary iovec structure */ + if (iovcnt > sizeof(tiov_stack)) { + tiovcnt = (sizeof(struct iovec) * UIO_MAXIOV); + if ((tiov = (struct iovec *)malloc(tiovcnt)) == NULL) + return -1 /* errno is set */; + } + else { + tiovcnt = sizeof(tiov_stack); + tiov = tiov_stack; + } /* init return value and number of bytes to write */ rv = 0; @@ -881,7 +894,7 @@ /* init local iovec structure */ liov = NULL; liovcnt = 0; - pth_writev_iov_advance(iov, iovcnt, 0, &liov, &liovcnt); + pth_writev_iov_advance(iov, iovcnt, 0, &liov, &liovcnt, tiov, tiovcnt); /* first directly poll filedescriptor for writeability to avoid unneccessary (and resource consuming because of context @@ -905,6 +918,8 @@ pth_event_isolate(ev); if (!pth_event_occurred(ev)) { pth_fdmode(fd, fdmode); + if (iovcnt > sizeof(tiov_stack)) + free(tiov); return_errno(-1, EINTR); } } @@ -926,7 +941,7 @@ we've to mimic the usual blocking I/O behaviour of writev(2) */ if (s > 0 && s < (ssize_t)nbytes) { nbytes -= s; - pth_writev_iov_advance(iov, iovcnt, s, &liov, &liovcnt); + pth_writev_iov_advance(iov, iovcnt, s, &liov, &liovcnt, tiov, tiovcnt); n = 0; continue; } @@ -938,6 +953,10 @@ /* stop looping */ break; } + + /* cleanup */ + if (iovcnt > sizeof(tiov_stack)) + free(tiov); } else { /* just perform the actual write operation */ @@ -974,9 +993,9 @@ /* advance the virtual pointer of a struct iov */ intern void pth_writev_iov_advance(const struct iovec *riov, int riovcnt, size_t advance, - struct iovec **liov, int *liovcnt) + struct iovec **liov, int *liovcnt, + struct iovec *tiov, int tiovcnt) { - static struct iovec siov[UIO_MAXIOV]; int i; if (*liov == NULL && *liovcnt == 0) { @@ -987,10 +1006,10 @@ if (advance > 0) { if (*liov == riov && *liovcnt == riovcnt) { /* reinitialize with a copy to be able to adjust it */ - *liov = &siov[0]; + *liov = &tiov[0]; for (i = 0; i < riovcnt; i++) { - siov[i].iov_base = riov[i].iov_base; - siov[i].iov_len = riov[i].iov_len; + tiov[i].iov_base = riov[i].iov_base; + tiov[i].iov_len = riov[i].iov_len; } } /* advance the virtual pointer */