--- 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 */
|