readv() questions

Mark Pizzolato list-cygwin@subscriptions.pizzolato.net
Tue May 9 14:01:00 GMT 2006


On Tuesday, May 09, 2006 12:44 AM clayne wrote:

> [...]
>
> My actual readv() wrapping code is very basic and standard, so I don't 
> think
> it's doing anything evil or causing a problem:
>
>     400 size_t n_recv_iov(int s, const struct iovec *v, size_t c, int 
> tout)
>     401 {
>     402         size_t          br;
>     403         int             res;
>     404         struct timeval  to;
>     405         fd_set          fds, fds_m;
>     406
>     407         FD_ZERO(&fds_m);
>     408         FD_SET(s, &fds_m);
>     409
>     410         while (1) {
>     411                 fds = fds_m;
>     412                 to.tv_sec = tout;
>     413                 to.tv_usec = 0;
>     414
>     415                 if ((br = readv(s, v, c)) == (size_t)-1) {
>     416                         switch (errno) {
>     417                         case EWOULDBLOCK:
>     418                         case EINTR:
>     419                                 break;
>     420                         default:
>     421                                 perror("readv");
>     422                                 return -1;
>     423                         }
>     424                 } else {
>     425                         break;
>     426                 }
>     427
>     428                 if ((res = select(s + 1, &fds, NULL, NULL, &to)) 
> == 0)
>     429                         return -1; /* timeout */
>     430                 else if (res == -1) {
>     431                         perror("select");
>     432                         return -1; /* never happen */
>     433                 }
>     434         }
>     435
>     436         return br;
>     437 }
>
> And my call to it is basic as well:
>
>      61         IOV_SET(&packet[0], &byte_tl, sizeof(byte_tl));
>      62         IOV_SET(&packet[1], &byte_vl, sizeof(byte_vl));
>      63         IOV_SET(&packet[2], &byte_flags, sizeof(byte_flags));
>      64         IOV_SET(&packet[3], &nbo_s, sizeof(nbo_s));
>      65         IOV_SET(&packet[4], &nbo_t_onl, sizeof(nbo_t_onl));
>      66         IOV_SET(&packet[5], &nbo_t_ofl, sizeof(nbo_t_ofl));
>      67
>      68         for (error = 0; !error; ) {
>      69                 error = 1;
>      70
>      71                 if ((hl = n_recv_iov(s, packet, NE(packet), 60)) 
> == (size_t)-1)
>      72                         break;
>      73
>      74 assert(byte_vl < sizeof(byte_var));
>      75
>      76                 if ((vl = n_recv(s, byte_var, byte_vl, 60)) == 
> (size_t)-1)
>      77                         break;
>      78                 if (hl == 0 || vl == 0)
>      79                         break;
>      80
>      81                 error = 0;
>      82
>      83                 /* process_data(); */
>      84         }
>
> Sorry for the ultra mail, but I know for a fact that readv() on cygwin is
> doing bad things when faced with a lot of data to read from the wire. Any
> insights?

Well, to me this looks like a variation on the classic error made when 
coding applications which use tcp.  Specifically that there is a 1<->1 
crrespondence between sends( write, writev, etc) on the sending side to 
rcvs(read, readv, etc) on the recieving side.  TCP makes no such guarantee. 
It only guarantees tha the bytes put in on the sending side of the 
connection will come out in the same order on the recieving side.  No 
guarantee about the size of the respective reads of the data delivered.  If 
you are expecting to receive a certain size data element, the burden is 
yours to actually make sure you get as much data as you expect, and to 
continue reading until you are happy.

Your code does not seem to do anything to validate that the length of the 
data returned by readv is indeed what you expected.

- Mark Pizzolato 



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



More information about the Cygwin mailing list