X-Spam-Check-By: sourceware.org Date: Tue, 9 May 2006 22:11:35 -0700 From: clayne AT anodized DOT com To: cygwin AT cygwin DOT com Cc: dave DOT korn AT artimi DOT com Subject: Re: readv() questions Message-ID: <20060510051135.GK18330@ns1.anodized.com> References: <20060509143556 DOT GI18330 AT ns1 DOT anodized DOT com> <02ab01c67378$71ad2440$a501a8c0 AT CAM DOT ARTIMI DOT COM> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <02ab01c67378$71ad2440$a501a8c0@CAM.ARTIMI.COM> User-Agent: Mutt/1.5.11 X-Assp-Spam-Prob: 0.00000 X-Assp-Whitelisted: Yes X-Assp-Envelope-From: clayne AT ns1 DOT anodized DOT com X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com On Tue, May 09, 2006 at 03:54:16PM +0100, Dave Korn wrote: > > You cannot > > even use the idiom of "well let me just get the rest of this here and I'll > > make a request for the dropped data after." > > Yes you absolutely can. Who said you can't? You're just not trying. It > works fine. Well 85% of it was honestly whining in retrospect. > > If that's the cake to eat, > > then I'll just rewrite my readv wrapper to deal with it I guess. Not like > > that is trivial if data is disrupted mid-vector. :-| > > Yes, it so is trivial. It's barely the tiniest bit more complex than > dealing with restarting a call to read(). > > cheers, > DaveK Thanks for taking the time to go through the original mail Dave - I appreciate it. After refactoring (just kidding, I don't really subscrib to that word)^H^H modifying my original n_recv_iov() code to deal with the edge-of-MSS and other partial readv() occurences I'm not having a problem anymore - unsurprisingly. I actually just call my n_recv() (standard non-blocking linear read) to read remaining bytes of a partially filled vector because I'd rather not muck with the contents of the original iovec passed in. I just pass it to n_iov_offset() with the bytes read as a value-result argument which returns number of iovecs filled + offset within a partially filled iovec in the v-r arg. So far so good, but if anyone sees anything glaring might as well point it out - although this is not really CW related at this point. -cl New stuff: 400 size_t n_iov_offset(const struct iovec *v, const size_t c, size_t *os) 401 { 402 size_t l, cv; 403 404 for (cv = 0; cv < c; cv++) { 405 if ((l = v[cv].iov_len) > *os) break; 406 *os -= l; 407 } 408 409 return cv; 410 } 411 412 size_t n_iov_total(const struct iovec *v, const size_t c) 413 { 414 size_t cv, bt; 415 416 for (cv = bt = 0; cv < c; cv++) 417 bt += v[cv].iov_len; 418 419 return bt; 420 } 421 422 size_t n_recv_iov(const int s, const struct iovec *v, size_t c, int tout) 423 { 424 size_t cv, br, bre, brt = 0; 425 int res; 426 struct timeval to; 427 fd_set fds, fds_m; 428 429 FD_ZERO(&fds_m); 430 FD_SET(s, &fds_m); 431 432 bre = n_iov_total(v, c); 433 434 while (brt < bre) { 435 fds = fds_m; 436 to.tv_sec = tout; 437 to.tv_usec = 0; 438 439 if ((br = readv(s, v, c)) == (size_t)-1) { 440 switch (errno) { 441 case EWOULDBLOCK: 442 case EINTR: 443 break; 444 default: 445 perror("readv"); 446 return -1; 447 } 448 } else if (br) { 449 if ((brt += br) < bre) { 450 /* short read, mid-vector offset returned in br */ 451 cv = n_iov_offset(v, c, &br); 452 v += cv; 453 c -= cv; 454 455 if (br == 0) 456 continue; 457 458 /* call read if we're short mid-vector */ 459 br = n_recv(s, (char *)v->iov_base + br, 460 v->iov_len - br, tout); 461 if (br == (size_t)-1) 462 return -1; 463 464 /* done with mid-vector fill, proceed with rest */ 465 brt += br; 466 v++; 467 c--; 468 } 469 } else { 470 break; 471 } 472 473 if ((res = select(s + 1, &fds, NULL, NULL, &to)) == 0) 474 return -1; /* timeout */ 475 else if (res == -1) { 476 perror("select"); /* never happen */ 477 return -1; 478 } 479 } 480 481 return brt; 482 } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/