This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: readv() questions


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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]