tls: refactor write queues away
The TLS implementation previously had two separate queues for WriteWrap instances, one for currently active and one for finishing writes (i.e. where the encrypted output is being written to the underlying socket). However, the streams implementation in Node doesn’t allow for more than one write to be active at a time; effectively, the only possible states were that: - No write was active. - The first write queue had one item, the second one was empty. - Only the second write queue had one item, the first one was empty. To reduce overhead and implementation complexity, remove these queues, and instead store a single `WriteWrap` pointer and keep track of whether its write callback should be called on the next invocation of `InvokeQueued()` or not (which is what being in the second queue previously effected). PR-URL: https://github.com/nodejs/node/pull/17883 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
parent
b171adc4d1
commit
d5fa4de00f
@ -120,20 +120,18 @@ TLSWrap::~TLSWrap() {
|
|||||||
|
|
||||||
|
|
||||||
void TLSWrap::MakePending() {
|
void TLSWrap::MakePending() {
|
||||||
write_item_queue_.MoveBack(&pending_write_items_);
|
write_callback_scheduled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TLSWrap::InvokeQueued(int status, const char* error_str) {
|
bool TLSWrap::InvokeQueued(int status, const char* error_str) {
|
||||||
if (pending_write_items_.IsEmpty())
|
if (!write_callback_scheduled_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Process old queue
|
if (current_write_ != nullptr) {
|
||||||
WriteItemList queue;
|
WriteWrap* w = current_write_;
|
||||||
pending_write_items_.MoveBack(&queue);
|
current_write_ = nullptr;
|
||||||
while (WriteItem* wi = queue.PopFront()) {
|
w->Done(status, error_str);
|
||||||
wi->w_->Done(status, error_str);
|
|
||||||
delete wi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -303,7 +301,7 @@ void TLSWrap::EncOut() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Split-off queue
|
// Split-off queue
|
||||||
if (established_ && !write_item_queue_.IsEmpty())
|
if (established_ && current_write_ != nullptr)
|
||||||
MakePending();
|
MakePending();
|
||||||
|
|
||||||
if (ssl_ == nullptr)
|
if (ssl_ == nullptr)
|
||||||
@ -606,8 +604,9 @@ int TLSWrap::DoWrite(WriteWrap* w,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue callback to execute it on next tick
|
// Store the current write wrap
|
||||||
write_item_queue_.PushBack(new WriteItem(w));
|
CHECK_EQ(current_write_, nullptr);
|
||||||
|
current_write_ = w;
|
||||||
w->Dispatched();
|
w->Dispatched();
|
||||||
|
|
||||||
// Write queued data
|
// Write queued data
|
||||||
|
@ -90,19 +90,6 @@ class TLSWrap : public AsyncWrap,
|
|||||||
// Maximum number of buffers passed to uv_write()
|
// Maximum number of buffers passed to uv_write()
|
||||||
static const int kSimultaneousBufferCount = 10;
|
static const int kSimultaneousBufferCount = 10;
|
||||||
|
|
||||||
// Write callback queue's item
|
|
||||||
class WriteItem {
|
|
||||||
public:
|
|
||||||
explicit WriteItem(WriteWrap* w) : w_(w) {
|
|
||||||
}
|
|
||||||
~WriteItem() {
|
|
||||||
w_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteWrap* w_;
|
|
||||||
ListNode<WriteItem> member_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TLSWrap(Environment* env,
|
TLSWrap(Environment* env,
|
||||||
Kind kind,
|
Kind kind,
|
||||||
StreamBase* stream,
|
StreamBase* stream,
|
||||||
@ -173,9 +160,8 @@ class TLSWrap : public AsyncWrap,
|
|||||||
BIO* enc_out_;
|
BIO* enc_out_;
|
||||||
crypto::NodeBIO* clear_in_;
|
crypto::NodeBIO* clear_in_;
|
||||||
size_t write_size_;
|
size_t write_size_;
|
||||||
typedef ListHead<WriteItem, &WriteItem::member_> WriteItemList;
|
WriteWrap* current_write_ = nullptr;
|
||||||
WriteItemList write_item_queue_;
|
bool write_callback_scheduled_ = false;
|
||||||
WriteItemList pending_write_items_;
|
|
||||||
bool started_;
|
bool started_;
|
||||||
bool established_;
|
bool established_;
|
||||||
bool shutdown_;
|
bool shutdown_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user