diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 95584218..5e21502c 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -434,11 +434,9 @@ int Http2Handler::write_clear() { auto loop = sessions_->get_loop(); for (;;) { if (wb_.rleft() > 0) { - struct iovec iov[2]; - auto iovcnt = wb_.riovec(iov); - ssize_t nwrite; - while ((nwrite = writev(fd_, iov, iovcnt)) == -1 && errno == EINTR) + while ((nwrite = write(fd_, wb_.pos, wb_.rleft())) == -1 && + errno == EINTR) ; if (nwrite == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -562,11 +560,7 @@ int Http2Handler::write_tls() { for (;;) { if (wb_.rleft() > 0) { - const void *p; - size_t len; - std::tie(p, len) = wb_.get(); - - auto rv = SSL_write(ssl_, p, len); + auto rv = SSL_write(ssl_, wb_.pos, wb_.rleft()); if (rv == 0) { return -1; diff --git a/src/HttpServer.h b/src/HttpServer.h index 67a4d11d..222daeb7 100644 --- a/src/HttpServer.h +++ b/src/HttpServer.h @@ -44,7 +44,7 @@ #include #include "http2.h" -#include "ringbuf.h" +#include "buffer.h" namespace nghttp2 { @@ -143,7 +143,7 @@ private: ev_io rev_; ev_timer settings_timerev_; std::map> id2stream_; - RingBuf<65536> wb_; + Buffer<65536> wb_; std::function read_, write_; int64_t session_id_; nghttp2_session *session_; diff --git a/src/Makefile.am b/src/Makefile.am index a68a9ae9..4b274327 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,8 +76,7 @@ nghttp_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttp.cc nghttp.h \ nghttpd_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttpd.cc \ ssl.cc ssl.h \ - HttpServer.cc HttpServer.h \ - ringbuf.h + HttpServer.cc HttpServer.h bin_PROGRAMS += h2load @@ -142,7 +141,6 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \ util_test.cc util_test.h \ nghttp2_gzip_test.c nghttp2_gzip_test.h \ nghttp2_gzip.c nghttp2_gzip.h \ - ringbuf_test.cc ringbuf_test.h \ buffer_test.cc buffer_test.h \ memchunk_test.cc memchunk_test.h nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS}\ diff --git a/src/buffer_test.cc b/src/buffer_test.cc index 99c66089..38688edc 100644 --- a/src/buffer_test.cc +++ b/src/buffer_test.cc @@ -45,7 +45,7 @@ void test_buffer_write(void) { CU_ASSERT(3 == b.rleft()); CU_ASSERT(13 == b.wleft()); - CU_ASSERT(0 == b.pos - std::begin(b.buf)); + CU_ASSERT(b.pos == std::begin(b.buf)); b.drain(3); @@ -65,14 +65,14 @@ void test_buffer_write(void) { b.reset(); CU_ASSERT(0 == b.rleft()); - CU_ASSERT(0 == b.wleft()); - CU_ASSERT(0 == b.pos - std::begin(b.buf)); + CU_ASSERT(16 == b.wleft()); + CU_ASSERT(b.pos == std::begin(b.buf)); b.write(5); CU_ASSERT(5 == b.rleft()); CU_ASSERT(11 == b.wleft()); - CU_ASSERT(0 == b.pos - std::begin(b.buf)); + CU_ASSERT(b.pos == std::begin(b.buf)); } } // namespace nghttp2 diff --git a/src/h2load.cc b/src/h2load.cc index 9539dcdf..6cbcd164 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -516,11 +516,8 @@ int Client::read_clear() { int Client::write_clear() { for (;;) { if (wb.rleft() > 0) { - struct iovec iov[2]; - auto iovcnt = wb.riovec(iov); - ssize_t nwrite; - while ((nwrite = writev(fd, iov, iovcnt)) == -1 && errno == EINTR) + while ((nwrite = write(fd, wb.pos, wb.rleft())) == -1 && errno == EINTR) ; if (nwrite == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -642,11 +639,7 @@ int Client::write_tls() { for (;;) { if (wb.rleft() > 0) { - const void *p; - size_t len; - std::tie(p, len) = wb.get(); - - auto rv = SSL_write(ssl, p, len); + auto rv = SSL_write(ssl, wb.pos, wb.rleft()); if (rv == 0) { return -1; diff --git a/src/h2load.h b/src/h2load.h index 7a624940..7ba6e95d 100644 --- a/src/h2load.h +++ b/src/h2load.h @@ -45,7 +45,7 @@ #include #include "http2.h" -#include "ringbuf.h" +#include "buffer.h" using namespace nghttp2; @@ -174,7 +174,7 @@ struct Client { // The number of requests this client has done so far. size_t req_done; int fd; - RingBuf<65536> wb; + Buffer<65536> wb; enum { ERR_CONNECT_FAIL = -100 }; diff --git a/src/nghttp.cc b/src/nghttp.cc index 6285484e..80fad936 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -652,11 +652,8 @@ int HttpClient::write_clear() { for (;;) { if (wb.rleft() > 0) { - struct iovec iov[2]; - auto iovcnt = wb.riovec(iov); - ssize_t nwrite; - while ((nwrite = writev(fd, iov, iovcnt)) == -1 && errno == EINTR) + while ((nwrite = write(fd, wb.pos, wb.rleft())) == -1 && errno == EINTR) ; if (nwrite == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { @@ -1147,11 +1144,7 @@ int HttpClient::write_tls() { for (;;) { if (wb.rleft() > 0) { - const void *p; - size_t len; - std::tie(p, len) = wb.get(); - - auto rv = SSL_write(ssl, p, len); + auto rv = SSL_write(ssl, wb.pos, wb.rleft()); if (rv == 0) { return -1; diff --git a/src/nghttp.h b/src/nghttp.h index 2ee7ffbc..14b89f94 100644 --- a/src/nghttp.h +++ b/src/nghttp.h @@ -45,7 +45,7 @@ #include "http-parser/http_parser.h" -#include "ringbuf.h" +#include "buffer.h" #include "http2.h" #include "nghttp2_gzip.h" @@ -261,7 +261,7 @@ struct HttpClient { // true if the response message of HTTP Upgrade request is fully // received. It is not relevant the upgrade succeeds, or not. bool upgrade_response_complete; - RingBuf<65536> wb; + Buffer<65536> wb; // SETTINGS payload sent as token68 in HTTP Upgrade std::array settings_payload; diff --git a/src/ringbuf.h b/src/ringbuf.h deleted file mode 100644 index 867293c5..00000000 --- a/src/ringbuf.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef RINGBUF_H -#define RINGBUF_H - -#include "nghttp2_config.h" - -#include - -#include -#include - -namespace nghttp2 { - -template struct RingBuf { - RingBuf() : pos(0), len(0) {} - // Returns the number of bytes to read. - size_t rleft() const { return len; } - // Returns the number of bytes this buffer can store. - size_t wleft() const { return N - len; } - // Writes up to min(wleft(), |count|) bytes from buffer pointed by - // |buf|. Returns number of bytes written. - size_t write(const void *buf, size_t count) { - count = std::min(count, wleft()); - auto last = (pos + len) % N; - if (count > N - last) { - auto c = N - last; - memcpy(begin + last, buf, c); - memcpy(begin, reinterpret_cast(buf) + c, count - c); - } else { - memcpy(begin + last, buf, count); - } - len += count; - return count; - } - size_t write(size_t count) { - count = std::min(count, wleft()); - len += count; - return count; - } - // Drains min(rleft(), |count|) bytes from start of the buffer. - size_t drain(size_t count) { - count = std::min(count, rleft()); - pos = (pos + count) % N; - len -= count; - return count; - } - // Returns pointer to the next contiguous readable buffer and its - // length. - std::pair get() const { - if (pos + len > N) { - return {begin + pos, N - pos}; - } - return {begin + pos, len}; - } - void reset() { pos = len = 0; } - // Fills |iov| for reading. |iov| must contain at least 2 elements. - // Returns the number of filled elements. - int riovec(struct iovec *iov) { - if (len == 0) { - return 0; - } - if (pos + len > N) { - auto c = N - pos; - iov[0].iov_base = begin + pos; - iov[0].iov_len = c; - iov[1].iov_base = begin; - iov[1].iov_len = len - c; - return 2; - } - iov[0].iov_base = begin + pos; - iov[0].iov_len = len; - return 1; - } - // Fills |iov| for writing. |iov| must contain at least 2 elements. - // Returns the number of filled elements. - int wiovec(struct iovec *iov) { - if (len == N) { - return 0; - } - if (pos == 0) { - iov[0].iov_base = begin + pos + len; - iov[0].iov_len = N - pos - len; - return 1; - } - if (pos + len < N) { - auto c = N - pos - len; - iov[0].iov_base = begin + pos + len; - iov[0].iov_len = c; - iov[1].iov_base = begin; - iov[1].iov_len = N - len - c; - return 2; - } - auto last = (pos + len) % N; - iov[0].iov_base = begin + last; - iov[0].iov_len = N - len; - return 1; - } - size_t pos; - size_t len; - uint8_t begin[N]; -}; - -} // namespace nghttp2 - -#endif // RINGBUF_H diff --git a/src/ringbuf_test.cc b/src/ringbuf_test.cc deleted file mode 100644 index ec530498..00000000 --- a/src/ringbuf_test.cc +++ /dev/null @@ -1,183 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "ringbuf_test.h" - -#include -#include -#include - -#include - -#include - -#include "ringbuf.h" - -namespace nghttp2 { - -void test_ringbuf_write(void) { - RingBuf<16> b; - CU_ASSERT(0 == b.rleft()); - CU_ASSERT(16 == b.wleft()); - - b.write("012", 3); - - CU_ASSERT(3 == b.rleft()); - CU_ASSERT(13 == b.wleft()); - CU_ASSERT(0 == b.pos); - CU_ASSERT(3 == b.len); - - b.drain(3); - - CU_ASSERT(0 == b.rleft()); - CU_ASSERT(16 == b.wleft()); - CU_ASSERT(3 == b.pos); - CU_ASSERT(0 == b.len); - - b.write("0123456789ABCDEF", 16); - - CU_ASSERT(16 == b.rleft()); - CU_ASSERT(0 == b.wleft()); - CU_ASSERT(3 == b.pos); - CU_ASSERT(16 == b.len); - CU_ASSERT(0 == memcmp(b.begin, "DEF0123456789ABC", 16)); - - const void *p; - size_t len; - std::tie(p, len) = b.get(); - CU_ASSERT(13 == len); - CU_ASSERT(0 == memcmp(p, "0123456789ABC", len)); - - b.drain(14); - - CU_ASSERT(2 == b.rleft()); - CU_ASSERT(14 == b.wleft()); - CU_ASSERT(1 == b.pos); - CU_ASSERT(2 == b.len); - - std::tie(p, len) = b.get(); - CU_ASSERT(2 == len); - CU_ASSERT(0 == memcmp(p, "EF", len)); -} - -void test_ringbuf_iovec(void) { - RingBuf<16> b; - struct iovec iov[2]; - - auto rv = b.riovec(iov); - - CU_ASSERT(0 == rv); - - rv = b.wiovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin == iov[0].iov_base); - CU_ASSERT(16 == iov[0].iov_len); - - // set pos to somewhere middle of the buffer, this will require 2 - // iovec for writing. - b.pos = 6; - - rv = b.riovec(iov); - - CU_ASSERT(0 == rv); - - rv = b.wiovec(iov); - - CU_ASSERT(2 == rv); - CU_ASSERT(b.begin + b.pos == iov[0].iov_base); - CU_ASSERT(10 == iov[0].iov_len); - CU_ASSERT(b.begin == iov[1].iov_base); - CU_ASSERT(6 == iov[1].iov_len); - - // occupy first region of buffer - b.pos = 0; - b.len = 10; - - rv = b.riovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin == iov[0].iov_base); - CU_ASSERT(10 == iov[0].iov_len); - - rv = b.wiovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin + b.len == iov[0].iov_base); - CU_ASSERT(6 == iov[0].iov_len); - - // occupy last region of buffer - b.pos = 6; - b.len = 10; - - rv = b.riovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin + b.pos == iov[0].iov_base); - CU_ASSERT(10 == iov[0].iov_len); - - rv = b.wiovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin == iov[0].iov_base); - CU_ASSERT(6 == iov[0].iov_len); - - // occupy middle of buffer - b.pos = 3; - b.len = 10; - - rv = b.riovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin + b.pos == iov[0].iov_base); - CU_ASSERT(10 == iov[0].iov_len); - - rv = b.wiovec(iov); - - CU_ASSERT(2 == rv); - CU_ASSERT(b.begin + b.pos + b.len == iov[0].iov_base); - CU_ASSERT(3 == iov[0].iov_len); - CU_ASSERT(b.begin == iov[1].iov_base); - CU_ASSERT(3 == iov[1].iov_len); - - // crossover - b.pos = 13; - b.len = 10; - - rv = b.riovec(iov); - - CU_ASSERT(2 == rv); - CU_ASSERT(b.begin + b.pos == iov[0].iov_base); - CU_ASSERT(3 == iov[0].iov_len); - CU_ASSERT(b.begin == iov[1].iov_base); - CU_ASSERT(7 == iov[1].iov_len); - - rv = b.wiovec(iov); - - CU_ASSERT(1 == rv); - CU_ASSERT(b.begin + 7 == iov[0].iov_base); - CU_ASSERT(6 == iov[0].iov_len); -} - -} // namespace nghttp2 diff --git a/src/ringbuf_test.h b/src/ringbuf_test.h deleted file mode 100644 index c7c42a27..00000000 --- a/src/ringbuf_test.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2014 Tatsuhiro Tsujikawa - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef RINGBUF_TEST_H -#define RINGBUF_TEST_H - -namespace nghttp2 { - -void test_ringbuf_write(void); -void test_ringbuf_iovec(void); - -} // namespace nghttp2 - -#endif // RINGBUF_TEST_H diff --git a/src/shrpx-unittest.cc b/src/shrpx-unittest.cc index b4b4af9e..bb6fd05f 100644 --- a/src/shrpx-unittest.cc +++ b/src/shrpx-unittest.cc @@ -38,7 +38,6 @@ #include "http2_test.h" #include "util_test.h" #include "nghttp2_gzip_test.h" -#include "ringbuf_test.h" #include "buffer_test.h" #include "memchunk_test.h" #include "shrpx_config.h" @@ -144,9 +143,7 @@ int main(int argc, char *argv[]) { !CU_add_test(pSuite, "util_format_duration", shrpx::test_util_format_duration) || !CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) || - !CU_add_test(pSuite, "ringbuf_write", nghttp2::test_ringbuf_write) || - !CU_add_test(pSuite, "ringbuf_iovec", nghttp2::test_ringbuf_iovec) || - !CU_add_test(pSuite, "buffer_write", nghttp2::test_ringbuf_write) || + !CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) || !CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) || !CU_add_test(pSuite, "memchunk_append", nghttp2::test_memchunks_append) || !CU_add_test(pSuite, "memchunk_drain", nghttp2::test_memchunks_drain) || diff --git a/src/template.h b/src/template.h index 77a230ca..c1fea1d7 100644 --- a/src/template.h +++ b/src/template.h @@ -29,6 +29,7 @@ #include #include +#include namespace nghttp2 {