diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-03-06 18:04:13 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-03-06 18:04:13 +0100 |
commit | 30b78bc2f4f7b74574abfbb3a3c2dc04686d2e7d (patch) | |
tree | 6350a96f7d9fbc487bf2604e5d90ab2a31384d4b /src | |
parent | 11b10ac8a4193e6804778a3284945ce0828be4c1 (diff) | |
parent | 56b7e9f8bf32824e0725005fcd0d2fa14a4ce088 (diff) |
Merge branch 'master+writev'
Diffstat (limited to 'src')
-rw-r--r-- | src/inspsocket.cpp | 51 | ||||
-rw-r--r-- | src/socketengine.cpp | 27 |
2 files changed, 30 insertions, 48 deletions
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index ee5287e5f..2646e265f 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -25,14 +25,6 @@ #include "inspircd.h" #include "iohook.h" -#ifndef DISABLE_WRITEV -#include <sys/uio.h> -#endif - -#ifndef IOV_MAX -#define IOV_MAX 1024 -#endif - BufferedSocket::BufferedSocket() { Timeout = NULL; @@ -225,9 +217,7 @@ void StreamSocket::DoWrite() return; } -#ifndef DISABLE_WRITEV if (GetIOHook()) -#endif { int rv = -1; try @@ -254,7 +244,7 @@ void StreamSocket::DoWrite() } std::string& front = sendq.front(); int itemlen = front.length(); - if (GetIOHook()) + { rv = GetIOHook()->OnStreamSocketWrite(this, front); if (rv > 0) @@ -278,39 +268,6 @@ void StreamSocket::DoWrite() return; } } -#ifdef DISABLE_WRITEV - else - { - rv = SocketEngine::Send(this, front.data(), itemlen, 0); - if (rv == 0) - { - SetError("Connection closed"); - return; - } - else if (rv < 0) - { - if (errno == EINTR || SocketEngine::IgnoreError()) - SocketEngine::ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); - else - SetError(SocketEngine::LastError()); - return; - } - else if (rv < itemlen) - { - SocketEngine::ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); - front.erase(0, rv); - sendq_len -= rv; - return; - } - else - { - sendq_len -= itemlen; - sendq.pop_front(); - if (sendq.empty()) - SocketEngine::ChangeEventMask(this, FD_WANT_EDGE_WRITE); - } - } -#endif } } catch (CoreException& modexcept) @@ -319,7 +276,6 @@ void StreamSocket::DoWrite() modexcept.GetSource().c_str(), modexcept.GetReason().c_str()); } } -#ifndef DISABLE_WRITEV else { // don't even try if we are known to be blocking @@ -341,14 +297,14 @@ void StreamSocket::DoWrite() int rv_max = 0; int rv; { - iovec iovecs[MYIOV_MAX]; + SocketEngine::IOVector iovecs[MYIOV_MAX]; for (int i = 0; i < bufcount; i++) { iovecs[i].iov_base = const_cast<char*>(sendq[i].data()); iovecs[i].iov_len = sendq[i].length(); rv_max += sendq[i].length(); } - rv = writev(fd, iovecs, bufcount); + rv = SocketEngine::WriteV(this, iovecs, bufcount); } if (rv == (int)sendq_len) @@ -412,7 +368,6 @@ void StreamSocket::DoWrite() SocketEngine::ChangeEventMask(this, eventChange); } } -#endif } void StreamSocket::WriteData(const std::string &data) diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 1c91ccdea..eadfc73d3 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -224,6 +224,33 @@ int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flag return nbSent; } +int SocketEngine::WriteV(EventHandler* fd, const IOVector* iovec, int count) +{ + int sent = writev(fd->GetFd(), iovec, count); + if (sent > 0) + stats.Update(0, sent); + return sent; +} + +#ifdef _WIN32 +int SocketEngine::WriteV(EventHandler* fd, const iovec* iovec, int count) +{ + // On Windows the fields in iovec are not in the order required by the Winsock API; IOVector has + // the fields in the correct order. + // Create temporary IOVectors from the iovecs and pass them to the WriteV() method that accepts the + // platform's native struct. + IOVector wiovec[128]; + count = std::min(count, static_cast<int>(sizeof(wiovec) / sizeof(IOVector))); + + for (int i = 0; i < count; i++) + { + wiovec[i].iov_len = iovec[i].iov_len; + wiovec[i].iov_base = reinterpret_cast<char*>(iovec[i].iov_base); + } + return WriteV(fd, wiovec, count); +} +#endif + int SocketEngine::Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen) { int ret = connect(fd->GetFd(), serv_addr, addrlen); |