Skip to content

Commit 75cfb13

Browse files
RafaelGSSaddaleax
andcommitted
src: make ReqWrap weak
This commit allows throwing an exception after creating `FSReqCallback` Co-authored-by: Anna Henningsen <anna@addaleax.net> PR-URL: #44074 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 9da1142 commit 75cfb13

7 files changed

+15
-18
lines changed

lib/fs.js

-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424

2525
'use strict';
2626

27-
// When using FSReqCallback, make sure to create the object only *after* all
28-
// parameter validation has happened, so that the objects are not kept in memory
29-
// in case they are created but never used due to an exception.
30-
3127
const {
3228
ArrayPrototypePush,
3329
BigIntPrototypeToString,

src/cares_wrap.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
14291429

14301430
void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
14311431
auto cleanup = OnScopeLeave([&]() { uv_freeaddrinfo(res); });
1432-
std::unique_ptr<GetAddrInfoReqWrap> req_wrap {
1432+
BaseObjectPtr<GetAddrInfoReqWrap> req_wrap{
14331433
static_cast<GetAddrInfoReqWrap*>(req->data)};
14341434
Environment* env = req_wrap->env();
14351435

@@ -1502,7 +1502,7 @@ void AfterGetNameInfo(uv_getnameinfo_t* req,
15021502
int status,
15031503
const char* hostname,
15041504
const char* service) {
1505-
std::unique_ptr<GetNameInfoReqWrap> req_wrap {
1505+
BaseObjectPtr<GetNameInfoReqWrap> req_wrap{
15061506
static_cast<GetNameInfoReqWrap*>(req->data)};
15071507
Environment* env = req_wrap->env();
15081508

src/connection_wrap.cc

+2-3
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,8 @@ void ConnectionWrap<WrapType, UVType>::OnConnection(uv_stream_t* handle,
7777
template <typename WrapType, typename UVType>
7878
void ConnectionWrap<WrapType, UVType>::AfterConnect(uv_connect_t* req,
7979
int status) {
80-
std::unique_ptr<ConnectWrap> req_wrap
81-
(static_cast<ConnectWrap*>(req->data));
82-
CHECK_NOT_NULL(req_wrap);
80+
BaseObjectPtr<ConnectWrap> req_wrap{static_cast<ConnectWrap*>(req->data)};
81+
CHECK(req_wrap);
8382
WrapType* wrap = static_cast<WrapType*>(req->handle->data);
8483
CHECK_EQ(req_wrap->env(), wrap->env());
8584
Environment* env = wrap->env();

src/node_file.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@ MaybeLocal<Promise> FileHandle::ClosePromise() {
460460

461461
CloseReq* req = new CloseReq(env(), close_req_obj, promise, object());
462462
auto AfterClose = uv_fs_callback_t{[](uv_fs_t* req) {
463-
std::unique_ptr<CloseReq> close(CloseReq::from_req(req));
464-
CHECK_NOT_NULL(close);
463+
BaseObjectPtr<CloseReq> close(CloseReq::from_req(req));
464+
CHECK(close);
465465
close->file_handle()->AfterClose();
466466
if (!close->env()->can_call_into_js()) return;
467467
Isolate* isolate = close->env()->isolate();

src/req_wrap-inl.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@ ReqWrap<T>::ReqWrap(Environment* env,
2020
AsyncWrap::ProviderType provider)
2121
: AsyncWrap(env, object, provider),
2222
ReqWrapBase(env) {
23+
MakeWeak();
2324
Reset();
2425
}
2526

2627
template <typename T>
27-
ReqWrap<T>::~ReqWrap() {
28-
CHECK_EQ(false, persistent().IsEmpty());
29-
}
28+
ReqWrap<T>::~ReqWrap() {}
3029

3130
template <typename T>
3231
void ReqWrap<T>::Dispatched() {
@@ -120,7 +119,8 @@ struct MakeLibuvRequestCallback<ReqT, void(*)(ReqT*, Args...)> {
120119
using F = void(*)(ReqT* req, Args... args);
121120

122121
static void Wrapper(ReqT* req, Args... args) {
123-
ReqWrap<ReqT>* req_wrap = ReqWrap<ReqT>::from_req(req);
122+
BaseObjectPtr<ReqWrap<ReqT>> req_wrap{ReqWrap<ReqT>::from_req(req)};
123+
req_wrap->Detach();
124124
req_wrap->env()->DecreaseWaitingRequestCounter();
125125
F original_callback = reinterpret_cast<F>(req_wrap->original_callback_);
126126
original_callback(req, args...);
@@ -138,7 +138,6 @@ template <typename T>
138138
template <typename LibuvFunction, typename... Args>
139139
int ReqWrap<T>::Dispatch(LibuvFunction fn, Args... args) {
140140
Dispatched();
141-
142141
// This expands as:
143142
//
144143
// int err = fn(env()->event_loop(), req(), arg1, arg2, Wrapper, arg3, ...)
@@ -158,8 +157,10 @@ int ReqWrap<T>::Dispatch(LibuvFunction fn, Args... args) {
158157
env()->event_loop(),
159158
req(),
160159
MakeLibuvRequestCallback<T, Args>::For(this, args)...);
161-
if (err >= 0)
160+
if (err >= 0) {
161+
ClearWeak();
162162
env()->IncreaseWaitingRequestCounter();
163+
}
163164
return err;
164165
}
165166

src/tcp_wrap.cc

+1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args,
344344
if (err) {
345345
delete req_wrap;
346346
} else {
347+
CHECK(args[2]->Uint32Value(env->context()).IsJust());
347348
int port = args[2]->Uint32Value(env->context()).FromJust();
348349
TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(TRACING_CATEGORY_NODE2(net, native),
349350
"connect",

src/udp_wrap.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ int UDPWrap::RecvStop() {
669669

670670

671671
void UDPWrap::OnSendDone(ReqWrap<uv_udp_send_t>* req, int status) {
672-
std::unique_ptr<SendWrap> req_wrap{static_cast<SendWrap*>(req)};
672+
BaseObjectPtr<SendWrap> req_wrap{static_cast<SendWrap*>(req)};
673673
if (req_wrap->have_callback()) {
674674
Environment* env = req_wrap->env();
675675
HandleScope handle_scope(env->isolate());

0 commit comments

Comments
 (0)