summaryrefslogtreecommitdiff
path: root/src/SocketCore.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-01-11 14:20:34 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2013-01-11 16:50:04 +0900
commit8ba0d58ee1a9fc2249839339549293ddc183fe66 (patch)
tree3fe0018527530e93fb01cf0ea76641193b75be5d /src/SocketCore.cc
parent74e570de379752508d7f363dd0d1a0c4ae8b7319 (diff)
Vectorized write for SocketBuffer to avoid small packet
Diffstat (limited to 'src/SocketCore.cc')
-rw-r--r--src/SocketCore.cc53
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)) {