+ int rv = writev(fd, iovecs, bufcount);
+ delete[] iovecs;
+
+ if (rv == (int)sendq_len)
+ {
+ // it's our lucky day, everything got written out. Fast cleanup.
+ // This won't ever happen if the number of buffers got capped.
+ sendq_len = 0;
+ sendq.clear();
+ }
+ else if (rv > 0)
+ {
+ // Partial write. Clean out strings from the sendq
+ if (rv < rv_max)
+ {
+ // it's going to block now
+ eventChange = FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK;
+ }
+ sendq_len -= rv;
+ while (rv > 0 && !sendq.empty())
+ {
+ std::string& front = sendq.front();
+ if (front.length() <= (size_t)rv)
+ {
+ // this string got fully written out
+ rv -= front.length();
+ sendq.pop_front();
+ }
+ else
+ {
+ // stopped in the middle of this string
+ front = front.substr(rv);
+ rv = 0;
+ }
+ }
+ }
+ else if (rv == 0)
+ {
+ error = "Connection closed";
+ }
+ else if (SocketEngine::IgnoreError())
+ {
+ eventChange = FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK;
+ }
+ else if (errno == EINTR)
+ {
+ // restart interrupted syscall
+ errno = 0;
+ }
+ else
+ {
+ error = SocketEngine::LastError();
+ }
+ }
+ if (!error.empty())
+ {
+ // error - kill all events
+ ServerInstance->SE->ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE);
+ }
+ else
+ {
+ ServerInstance->SE->ChangeEventMask(this, eventChange);