summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-11-28 02:49:30 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2013-12-07 03:47:57 +0400
commit03747f69fba646dc9902519c1736d5f4f267ef7b (patch)
tree8f77bcc99ae036a4574926dbf63cdbe418499c6c
parentf5ab3e4c5cd37b76d60f657190b315183dbefeba (diff)
downloadandroid-node-v8-03747f69fba646dc9902519c1736d5f4f267ef7b.tar.gz
android-node-v8-03747f69fba646dc9902519c1736d5f4f267ef7b.tar.bz2
android-node-v8-03747f69fba646dc9902519c1736d5f4f267ef7b.zip
tls_wrap: use writev when possible
Try writing multiple chunks from NodeBIO if possible.
-rw-r--r--src/node_crypto_bio.cc27
-rw-r--r--src/node_crypto_bio.h4
-rw-r--r--src/tls_wrap.cc13
-rw-r--r--src/tls_wrap.h3
4 files changed, 43 insertions, 4 deletions
diff --git a/src/node_crypto_bio.cc b/src/node_crypto_bio.cc
index 05a4b5f48f..84dc42b464 100644
--- a/src/node_crypto_bio.cc
+++ b/src/node_crypto_bio.cc
@@ -96,6 +96,33 @@ char* NodeBIO::Peek(size_t* size) {
}
+size_t NodeBIO::PeekMultiple(char** out, size_t* size, size_t* count) {
+ Buffer* pos = read_head_;
+ size_t max = *count;
+ size_t total = 0;
+
+ size_t i;
+ for (i = 0; i < max; i++) {
+ size[i] = pos->write_pos_ - pos->read_pos_;
+ total += size[i];
+ out[i] = pos->data_ + pos->read_pos_;
+
+ /* Don't get past write head */
+ if (pos == write_head_)
+ break;
+ else
+ pos = pos->next_;
+ }
+
+ if (i == max)
+ *count = i;
+ else
+ *count = i + 1;
+
+ return total;
+}
+
+
int NodeBIO::Write(BIO* bio, const char* data, int len) {
BIO_clear_retry_flags(bio);
diff --git a/src/node_crypto_bio.h b/src/node_crypto_bio.h
index 615fea944e..0b9b3440c5 100644
--- a/src/node_crypto_bio.h
+++ b/src/node_crypto_bio.h
@@ -55,6 +55,10 @@ class NodeBIO {
// contiguous data available to read
char* Peek(size_t* size);
+ // Return pointers and sizes of multiple internal data chunks available for
+ // reading
+ size_t PeekMultiple(char** out, size_t* size, size_t* count);
+
// Find first appearance of `delim` in buffer or `limit` if `delim`
// wasn't found.
size_t IndexOf(char delim, size_t limit);
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index 6ceb861be2..b7bce94706 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -263,12 +263,17 @@ void TLSCallbacks::EncOut() {
return;
}
- char* data = NodeBIO::FromBIO(enc_out_)->Peek(&write_size_);
- assert(write_size_ != 0);
+ char* data[kSimultaneousBufferCount];
+ size_t size[ARRAY_SIZE(data)];
+ size_t count = ARRAY_SIZE(data);
+ write_size_ = NodeBIO::FromBIO(enc_out_)->PeekMultiple(data, size, &count);
+ assert(write_size_ != 0 && count != 0);
write_req_.data = this;
- uv_buf_t buf = uv_buf_init(data, write_size_);
- int r = uv_write(&write_req_, wrap()->stream(), &buf, 1, EncOutCb);
+ uv_buf_t buf[ARRAY_SIZE(data)];
+ for (size_t i = 0; i < count; i++)
+ buf[i] = uv_buf_init(data[i], size[i]);
+ int r = uv_write(&write_req_, wrap()->stream(), buf, count, EncOutCb);
// Ignore errors, this should be already handled in js
if (!r) {
diff --git a/src/tls_wrap.h b/src/tls_wrap.h
index 924a7243c4..a5090cbe83 100644
--- a/src/tls_wrap.h
+++ b/src/tls_wrap.h
@@ -68,6 +68,9 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
protected:
static const int kClearOutChunkSize = 1024;
+ // Maximum number of buffers passed to uv_write()
+ static const int kSimultaneousBufferCount = 10;
+
// Write callback queue's item
class WriteItem {
public: