diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-01-11 14:20:34 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-01-11 16:50:04 +0900 |
| commit | 8ba0d58ee1a9fc2249839339549293ddc183fe66 (patch) | |
| tree | 3fe0018527530e93fb01cf0ea76641193b75be5d /src/SocketCore.cc | |
| parent | 74e570de379752508d7f363dd0d1a0c4ae8b7319 (diff) | |
Vectorized write for SocketBuffer to avoid small packet
Diffstat (limited to 'src/SocketCore.cc')
| -rw-r--r-- | src/SocketCore.cc | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 1be9010b..d8596009 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -738,14 +738,57 @@ void SocketCore::gnutlsRecordCheckDirection() } #endif // HAVE_LIBGNUTLS -ssize_t SocketCore::writeData(const char* data, size_t len) +ssize_t SocketCore::writeVector(a2iovec *iov, size_t iovcnt) +{ + ssize_t ret = 0; + wantRead_ = false; + wantWrite_ = false; + if(!secure_) { +#ifdef __MINGW32__ + DWORD nsent; + int rv = WSASend(sockfd_, iov, iovcnt, &nsent, 0, 0, 0); + if(rv == 0) { + ret = nsent; + } else { + ret = -1; + } +#else // !__MINGW32__ + while((ret = writev(sockfd_, iov, iovcnt)) == -1 && + SOCKET_ERRNO == A2_EINTR); +#endif // !__MINGW32__ + int errNum = SOCKET_ERRNO; + if(ret == -1) { + if(A2_WOULDBLOCK(errNum)) { + wantWrite_ = true; + ret = 0; + } else { + throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, errorMsg(errNum).c_str())); + } + } + } else { + // For SSL/TLS, we could not use writev, so just iterate vector + // and write the data in normal way. + for(size_t i = 0; i < iovcnt; ++i) { + ssize_t rv = writeData(iov[i].A2IOVEC_BASE, iov[i].A2IOVEC_LEN); + if(rv == 0) { + break; + } + ret += rv; + } + } + return ret; +} + +ssize_t SocketCore::writeData(const void* data, size_t len) { ssize_t ret = 0; wantRead_ = false; wantWrite_ = false; if(!secure_) { - while((ret = send(sockfd_, data, len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR); + // Cast for Windows send() + while((ret = send(sockfd_, reinterpret_cast<const char*>(data), + len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR); int errNum = SOCKET_ERRNO; if(ret == -1) { if(A2_WOULDBLOCK(errNum)) { @@ -1166,7 +1209,7 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname) #endif // ENABLE_SSL -ssize_t SocketCore::writeData(const char* data, size_t len, +ssize_t SocketCore::writeData(const void* data, size_t len, const std::string& host, uint16_t port) { wantRead_ = false; @@ -1184,7 +1227,9 @@ ssize_t SocketCore::writeData(const char* data, size_t len, ssize_t r = -1; int errNum = 0; for(rp = res; rp; rp = rp->ai_next) { - while((r = sendto(sockfd_, data, len, 0, rp->ai_addr, rp->ai_addrlen)) == -1 + // Cast for Windows sendto() + while((r = sendto(sockfd_, reinterpret_cast<const char*>(data), len, 0, + rp->ai_addr, rp->ai_addrlen)) == -1 && A2_EINTR == SOCKET_ERRNO); errNum = SOCKET_ERRNO; if(r == static_cast<ssize_t>(len)) { |
