pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/nodejs/node/commit/0e7b61229aa602e55c5fb034a63d7da97eecff3b

-6534fbc3f5e83ac0.css" /> src: refactor WriteWrap and ShutdownWraps · nodejs/node@0e7b612 · GitHub
Skip to content

Commit 0e7b612

Browse files
committed
src: refactor WriteWrap and ShutdownWraps
Encapsulate stream requests more: - `WriteWrap` and `ShutdownWrap` classes are now tailored to the streams on which they are used. In particular, for most streams these are now plain `AsyncWrap`s and do not carry the overhead of unused libuv request data. - Provide generic `Write()` and `Shutdown()` methods that wrap around the actual implementations, and make *usage* of streams easier, rather than implementing; for example, wrap objects don’t need to be provided by callers anymore. - Use `EmitAfterWrite()` and `EmitAfterShutdown()` handlers to call the corresponding JS handlers, rather than always trying to call them. This makes usage of streams by other C++ code easier and leaner. Also fix up some tests that were previously not actually testing asynchronicity when the comments indicated that they would. PR-URL: #18676 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 0ed9ea8 commit 0e7b612

20 files changed

Lines changed: 556 additions & 427 deletions

benchmark/net/tcp-raw-c2s.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ function client(type, len) {
118118
fail(err, 'write');
119119
}
120120

121-
function afterWrite(err, handle, req) {
121+
function afterWrite(err, handle) {
122122
if (err)
123123
fail(err, 'write');
124124

benchmark/net/tcp-raw-pipe.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function main({ dur, len, type }) {
5151
if (err)
5252
fail(err, 'write');
5353

54-
writeReq.oncomplete = function(status, handle, req, err) {
54+
writeReq.oncomplete = function(status, handle, err) {
5555
if (err)
5656
fail(err, 'write');
5757
};
@@ -130,7 +130,7 @@ function main({ dur, len, type }) {
130130
fail(err, 'write');
131131
}
132132

133-
function afterWrite(err, handle, req) {
133+
function afterWrite(err, handle) {
134134
if (err)
135135
fail(err, 'write');
136136

benchmark/net/tcp-raw-s2c.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ function main({ dur, len, type }) {
7474
fail(err, 'write');
7575
} else if (!writeReq.async) {
7676
process.nextTick(function() {
77-
afterWrite(null, clientHandle, writeReq);
77+
afterWrite(0, clientHandle);
7878
});
7979
}
8080
}
8181

82-
function afterWrite(status, handle, req, err) {
83-
if (err)
84-
fail(err, 'write');
82+
function afterWrite(status, handle) {
83+
if (status)
84+
fail(status, 'write');
8585

8686
while (clientHandle.writeQueueSize === 0)
8787
write();

lib/internal/http2/core.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,20 +1399,19 @@ function trackWriteState(stream, bytes) {
13991399
session[kHandle].chunksSentSinceLastWrite = 0;
14001400
}
14011401

1402-
function afterDoStreamWrite(status, handle, req) {
1402+
function afterDoStreamWrite(status, handle) {
14031403
const stream = handle[kOwner];
14041404
const session = stream[kSession];
14051405

14061406
stream[kUpdateTimer]();
14071407

1408-
const { bytes } = req;
1408+
const { bytes } = this;
14091409
stream[kState].writeQueueSize -= bytes;
14101410

14111411
if (session !== undefined)
14121412
session[kState].writeQueueSize -= bytes;
1413-
if (typeof req.callback === 'function')
1414-
req.callback(null);
1415-
req.handle = undefined;
1413+
if (typeof this.callback === 'function')
1414+
this.callback(null);
14161415
}
14171416

14181417
function streamOnResume() {

lib/internal/wrap_js_stream.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ class JSStreamWrap extends Socket {
115115

116116
const handle = this._handle;
117117

118-
this.stream.end(() => {
119-
// Ensure that write was dispatched
120-
setImmediate(() => {
118+
setImmediate(() => {
119+
// Ensure that write is dispatched asynchronously.
120+
this.stream.end(() => {
121121
this.finishShutdown(handle, 0);
122122
});
123123
});

lib/net.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ function onSocketFinish() {
335335
}
336336

337337

338-
function afterShutdown(status, handle, req) {
338+
function afterShutdown(status, handle) {
339339
var self = handle.owner;
340340

341341
debug('afterShutdown destroyed=%j', self.destroyed,
@@ -869,12 +869,12 @@ protoGetter('bytesWritten', function bytesWritten() {
869869
});
870870

871871

872-
function afterWrite(status, handle, req, err) {
872+
function afterWrite(status, handle, err) {
873873
var self = handle.owner;
874874
if (self !== process.stderr && self !== process.stdout)
875875
debug('afterWrite', status);
876876

877-
if (req.async)
877+
if (this.async)
878878
self[kLastWriteQueueSize] = 0;
879879

880880
// callback may come after call to destroy.
@@ -884,9 +884,9 @@ function afterWrite(status, handle, req, err) {
884884
}
885885

886886
if (status < 0) {
887-
var ex = errnoException(status, 'write', req.error);
887+
var ex = errnoException(status, 'write', this.error);
888888
debug('write failure', ex);
889-
self.destroy(ex, req.cb);
889+
self.destroy(ex, this.cb);
890890
return;
891891
}
892892

@@ -895,8 +895,8 @@ function afterWrite(status, handle, req, err) {
895895
if (self !== process.stderr && self !== process.stdout)
896896
debug('afterWrite call cb');
897897

898-
if (req.cb)
899-
req.cb.call(undefined);
898+
if (this.cb)
899+
this.cb.call(undefined);
900900
}
901901

902902

src/env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ class ModuleWrap;
306306
V(script_context_constructor_template, v8::FunctionTemplate) \
307307
V(script_data_constructor_function, v8::Function) \
308308
V(secure_context_constructor_template, v8::FunctionTemplate) \
309+
V(shutdown_wrap_constructor_function, v8::Function) \
309310
V(tcp_constructor_template, v8::FunctionTemplate) \
310311
V(tick_callback_function, v8::Function) \
311312
V(timers_callback_function, v8::Function) \

src/js_stream.cc

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ int JSStream::DoShutdown(ShutdownWrap* req_wrap) {
9191
req_wrap->object()
9292
};
9393

94-
req_wrap->Dispatched();
95-
9694
TryCatch try_catch(env()->isolate());
9795
Local<Value> value;
9896
int value_int = UV_EPROTO;
@@ -127,8 +125,6 @@ int JSStream::DoWrite(WriteWrap* w,
127125
bufs_arr
128126
};
129127

130-
w->Dispatched();
131-
132128
TryCatch try_catch(env()->isolate());
133129
Local<Value> value;
134130
int value_int = UV_EPROTO;
@@ -154,9 +150,8 @@ void JSStream::New(const FunctionCallbackInfo<Value>& args) {
154150

155151
template <class Wrap>
156152
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) {
157-
Wrap* w;
158153
CHECK(args[0]->IsObject());
159-
ASSIGN_OR_RETURN_UNWRAP(&w, args[0].As<Object>());
154+
Wrap* w = static_cast<Wrap*>(StreamReq::FromObject(args[0].As<Object>()));
160155

161156
w->Done(args[1]->Int32Value());
162157
}

src/node_http2.cc

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,18 +1552,9 @@ void Http2Session::SendPendingData() {
15521552

15531553
chunks_sent_since_last_write_++;
15541554

1555-
// DoTryWrite may modify both the buffer list start itself and the
1556-
// base pointers/length of the individual buffers.
1557-
uv_buf_t* writebufs = *bufs;
1558-
if (stream_->DoTryWrite(&writebufs, &count) != 0 || count == 0) {
1559-
// All writes finished synchronously, nothing more to do here.
1560-
ClearOutgoing(0);
1561-
return;
1562-
}
1563-
1564-
WriteWrap* req = AllocateSend();
1565-
if (stream_->DoWrite(req, writebufs, count, nullptr) != 0) {
1566-
req->Dispose();
1555+
StreamWriteResult res = underlying_stream()->Write(*bufs, count);
1556+
if (!res.async) {
1557+
ClearOutgoing(res.err);
15671558
}
15681559

15691560
DEBUG_HTTP2SESSION2(this, "wants data in return? %d",
@@ -1649,15 +1640,6 @@ inline void Http2Session::SetChunksSinceLastWrite(size_t n) {
16491640
chunks_sent_since_last_write_ = n;
16501641
}
16511642

1652-
// Allocates the data buffer used to pass outbound data to the i/o stream.
1653-
WriteWrap* Http2Session::AllocateSend() {
1654-
HandleScope scope(env()->isolate());
1655-
Local<Object> obj =
1656-
env()->write_wrap_constructor_function()
1657-
->NewInstance(env()->context()).ToLocalChecked();
1658-
return WriteWrap::New(env(), obj, static_cast<StreamBase*>(stream_));
1659-
}
1660-
16611643
// Callback used to receive inbound data from the i/o stream
16621644
void Http2Session::OnStreamRead(ssize_t nread, const uv_buf_t& buf) {
16631645
Http2Scope h2scope(this);
@@ -1833,20 +1815,15 @@ inline void Http2Stream::Close(int32_t code) {
18331815
DEBUG_HTTP2STREAM2(this, "closed with code %d", code);
18341816
}
18351817

1836-
1837-
inline void Http2Stream::Shutdown() {
1838-
CHECK(!this->IsDestroyed());
1839-
Http2Scope h2scope(this);
1840-
flags_ |= NGHTTP2_STREAM_FLAG_SHUT;
1841-
CHECK_NE(nghttp2_session_resume_data(session_->session(), id_),
1842-
NGHTTP2_ERR_NOMEM);
1843-
DEBUG_HTTP2STREAM(this, "writable side shutdown");
1844-
}
1845-
18461818
int Http2Stream::DoShutdown(ShutdownWrap* req_wrap) {
18471819
CHECK(!this->IsDestroyed());
1848-
req_wrap->Dispatched();
1849-
Shutdown();
1820+
{
1821+
Http2Scope h2scope(this);
1822+
flags_ |= NGHTTP2_STREAM_FLAG_SHUT;
1823+
CHECK_NE(nghttp2_session_resume_data(session_->session(), id_),
1824+
NGHTTP2_ERR_NOMEM);
1825+
DEBUG_HTTP2STREAM(this, "writable side shutdown");
1826+
}
18501827
req_wrap->Done(0);
18511828
return 0;
18521829
}
@@ -2038,7 +2015,6 @@ inline int Http2Stream::DoWrite(WriteWrap* req_wrap,
20382015
CHECK_EQ(send_handle, nullptr);
20392016
Http2Scope h2scope(this);
20402017
session_->SetChunksSinceLastWrite();
2041-
req_wrap->Dispatched();
20422018
if (!IsWritable()) {
20432019
req_wrap->Done(UV_EOF);
20442020
return 0;

src/node_http2.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,6 @@ class Http2Stream : public AsyncWrap,
601601

602602
inline void Close(int32_t code);
603603

604-
// Shutdown the writable side of the stream
605-
inline void Shutdown();
606-
607604
// Destroy this stream instance and free all held memory.
608605
inline void Destroy();
609606

@@ -818,6 +815,10 @@ class Http2Session : public AsyncWrap, public StreamListener {
818815

819816
inline void EmitStatistics();
820817

818+
inline StreamBase* underlying_stream() {
819+
return static_cast<StreamBase*>(stream_);
820+
}
821+
821822
void Start();
822823
void Stop();
823824
void Close(uint32_t code = NGHTTP2_NO_ERROR,
@@ -907,8 +908,6 @@ class Http2Session : public AsyncWrap, public StreamListener {
907908
template <get_setting fn>
908909
static void GetSettings(const FunctionCallbackInfo<Value>& args);
909910

910-
WriteWrap* AllocateSend();
911-
912911
uv_loop_t* event_loop() const {
913912
return env()->event_loop();
914913
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy