crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs | LICENSE

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