netwrite.cc (2299B)
1 #include "netbuffer" 2 #include "balancer/balancer" 3 #include "SocketHandling/socket/socket" 4 5 unsigned Netbuffer::netwrite (Socket &s, unsigned timeout) const { 6 PROFILE("Netbuffer::netwrite"); 7 8 debugmsg("About to write " << buf_sz << " bytes to fd " << s.fd() 9 << ", timeout " << timeout << '\n'); 10 11 if (!buf_sz) 12 return (0); 13 14 // Log to dump directory if requested 15 if (config.dumpdir().length()) { 16 ostringstream of; 17 of << config.dumpdir() << "/" << balancer.requestnr() << "." 18 << s.fd(); 19 FILE *f; 20 if ( (!(f = fopen (of.str().c_str(), "a"))) && 21 (!(f = fopen (of.str().c_str(), "w"))) ) { 22 warnmsg("Cannot write traffic log " << of.str() << ": " << 23 strerror(errno) << '\n'); 24 } else { 25 fwrite (buf_data, 1, buf_sz, f); 26 fclose (f); 27 } 28 } 29 30 // Send to the socket 31 unsigned totwritten = 0, ntries = 0; 32 while (totwritten < buf_sz) { 33 // Don't go beyond 5 tries. 34 if (++ntries > 4) { 35 ostringstream o; 36 o << "Network writing to fd " << s.fd() << " failed, " 37 << totwritten << " bytes sent of " << buf_sz; 38 throw Error(o.str()); 39 } 40 41 // Wait for the socket to become writeable. 42 if (timeout) { 43 Fdset set (timeout); 44 set.add (s); 45 set.wait_w(); 46 if (! set.writeable(s)) { 47 ostringstream o; 48 o << "Fd " << s.fd() << " failed to become writable within " 49 << timeout << " sec"; 50 throw Error(o.str()); 51 } 52 } 53 54 // Push bytes 55 ssize_t nwritten; 56 nwritten = write (s.fd(), buf_data + totwritten, buf_sz - totwritten); 57 58 // If any bytes were written, we're ok 59 // EINVAL / EINPROGRESS errors are handled as: retry 60 // All other errors mean the link is broken 61 if (nwritten >= 1) { 62 ntries = 0; 63 if (config.debug()) { 64 ostringstream o; 65 o << "Sent " << nwritten << " bytes to fd " << s.fd() << ": "; 66 for (unsigned i = totwritten; i < totwritten + nwritten; i++) 67 o << printable(buf_data[i]); 68 o << "\n"; 69 debugmsg(o.str()); 70 } 71 totwritten += nwritten; 72 } else if (errno == EINVAL || errno == EINPROGRESS) { 73 msg("Write warning: " << strerror(errno) << '\n'); 74 } else { 75 ostringstream o; 76 o << "Write/send failed: errno=" << int(errno) << ", " 77 << strerror(errno) << ", result=" << int(nwritten); 78 throw Error(o.str()); 79 } 80 } 81 82 return buf_sz; 83 } 84