Skip to content

Commit 03747f6

Browse files
committed
tls_wrap: use writev when possible
Try writing multiple chunks from NodeBIO if possible.
1 parent f5ab3e4 commit 03747f6

4 files changed

Lines changed: 43 additions & 4 deletions

File tree

src/node_crypto_bio.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,33 @@ char* NodeBIO::Peek(size_t* size) {
9696
}
9797

9898

99+
size_t NodeBIO::PeekMultiple(char** out, size_t* size, size_t* count) {
100+
Buffer* pos = read_head_;
101+
size_t max = *count;
102+
size_t total = 0;
103+
104+
size_t i;
105+
for (i = 0; i < max; i++) {
106+
size[i] = pos->write_pos_ - pos->read_pos_;
107+
total += size[i];
108+
out[i] = pos->data_ + pos->read_pos_;
109+
110+
/* Don't get past write head */
111+
if (pos == write_head_)
112+
break;
113+
else
114+
pos = pos->next_;
115+
}
116+
117+
if (i == max)
118+
*count = i;
119+
else
120+
*count = i + 1;
121+
122+
return total;
123+
}
124+
125+
99126
int NodeBIO::Write(BIO* bio, const char* data, int len) {
100127
BIO_clear_retry_flags(bio);
101128

src/node_crypto_bio.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class NodeBIO {
5555
// contiguous data available to read
5656
char* Peek(size_t* size);
5757

58+
// Return pointers and sizes of multiple internal data chunks available for
59+
// reading
60+
size_t PeekMultiple(char** out, size_t* size, size_t* count);
61+
5862
// Find first appearance of `delim` in buffer or `limit` if `delim`
5963
// wasn't found.
6064
size_t IndexOf(char delim, size_t limit);

src/tls_wrap.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,17 @@ void TLSCallbacks::EncOut() {
263263
return;
264264
}
265265

266-
char* data = NodeBIO::FromBIO(enc_out_)->Peek(&write_size_);
267-
assert(write_size_ != 0);
266+
char* data[kSimultaneousBufferCount];
267+
size_t size[ARRAY_SIZE(data)];
268+
size_t count = ARRAY_SIZE(data);
269+
write_size_ = NodeBIO::FromBIO(enc_out_)->PeekMultiple(data, size, &count);
270+
assert(write_size_ != 0 && count != 0);
268271

269272
write_req_.data = this;
270-
uv_buf_t buf = uv_buf_init(data, write_size_);
271-
int r = uv_write(&write_req_, wrap()->stream(), &buf, 1, EncOutCb);
273+
uv_buf_t buf[ARRAY_SIZE(data)];
274+
for (size_t i = 0; i < count; i++)
275+
buf[i] = uv_buf_init(data[i], size[i]);
276+
int r = uv_write(&write_req_, wrap()->stream(), buf, count, EncOutCb);
272277

273278
// Ignore errors, this should be already handled in js
274279
if (!r) {

src/tls_wrap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class TLSCallbacks : public crypto::SSLWrap<TLSCallbacks>,
6868
protected:
6969
static const int kClearOutChunkSize = 1024;
7070

71+
// Maximum number of buffers passed to uv_write()
72+
static const int kSimultaneousBufferCount = 10;
73+
7174
// Write callback queue's item
7275
class WriteItem {
7376
public:

0 commit comments

Comments
 (0)