Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
tls_wrap: use writev when possible
Browse files Browse the repository at this point in the history
Try writing multiple chunks from NodeBIO if possible.
  • Loading branch information
indutny committed Dec 6, 2013
1 parent f5ab3e4 commit 03747f6
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
27 changes: 27 additions & 0 deletions src/node_crypto_bio.cc
Expand Up @@ -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);

Expand Down
4 changes: 4 additions & 0 deletions src/node_crypto_bio.h
Expand Up @@ -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);
Expand Down
13 changes: 9 additions & 4 deletions src/tls_wrap.cc
Expand Up @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions src/tls_wrap.h
Expand Up @@ -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:
Expand Down

0 comments on commit 03747f6

Please sign in to comment.