Skip to content

Commit bef920c

Browse files
committed
src: fill in more details of the coroutine impl
1 parent 12e85b0 commit bef920c

File tree

5 files changed

+229
-193
lines changed

5 files changed

+229
-193
lines changed

src/coro/uv_awaitable.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ class UvFsAwaitable {
9292
// Access the raw request (useful before cleanup for stat, readdir, etc.)
9393
const uv_fs_t& req() const { return req_; }
9494

95+
// Returns a pointer to the underlying uv_req_t for cancellation support.
96+
// Used by TrackedAwaitable to register with the request counter and
97+
// cancellation infrastructure.
98+
uv_req_t* cancelable_req() { return reinterpret_cast<uv_req_t*>(&req_); }
99+
95100
private:
96101
static void OnComplete(uv_fs_t* req) {
97102
auto* self = static_cast<UvFsAwaitable*>(req->data);
@@ -196,6 +201,8 @@ class UvFsStatAwaitable {
196201
return r;
197202
}
198203

204+
uv_req_t* cancelable_req() { return reinterpret_cast<uv_req_t*>(&req_); }
205+
199206
private:
200207
static void OnComplete(uv_fs_t* req) {
201208
auto* self = static_cast<UvFsStatAwaitable*>(req->data);
@@ -258,6 +265,8 @@ class UvWorkAwaitable {
258265
// Returns 0 on success, UV_ECANCELED if cancelled, or negative error.
259266
int await_resume() noexcept { return status_; }
260267

268+
uv_req_t* cancelable_req() { return reinterpret_cast<uv_req_t*>(&req_); }
269+
261270
private:
262271
static void OnWork(uv_work_t* req) {
263272
auto* self = static_cast<UvWorkAwaitable*>(req->data);
@@ -331,6 +340,8 @@ class UvGetAddrInfoAwaitable {
331340

332341
AddrInfoResult await_resume() noexcept { return {status_, addrinfo_}; }
333342

343+
uv_req_t* cancelable_req() { return reinterpret_cast<uv_req_t*>(&req_); }
344+
334345
private:
335346
static void OnComplete(uv_getaddrinfo_t* req,
336347
int status,

src/coro/uv_promise.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ namespace coro {
1616
// on_resume() already provides a HandleScope and will drain microtasks
1717
// and nextTick on close (in on_suspend / final_suspend).
1818
//
19-
// When used inside an untracked UvTask (no InternalCallbackScope),
20-
// these create their own HandleScope.
19+
// These guard against calling V8 APIs when the environment is shutting
20+
// down (can_call_into_js() is false).
2121
// ---------------------------------------------------------------------------
2222

2323
inline void ResolvePromise(Environment* env,
2424
v8::Global<v8::Promise::Resolver>& resolver,
2525
v8::Local<v8::Value> value) {
26+
if (!env->can_call_into_js()) return;
2627
v8::HandleScope scope(env->isolate());
2728
auto local = resolver.Get(env->isolate());
2829
USE(local->Resolve(env->context(), value));
@@ -39,6 +40,7 @@ inline void RejectPromiseWithUVError(
3940
int uv_err,
4041
const char* syscall,
4142
const char* path = nullptr) {
43+
if (!env->can_call_into_js()) return;
4244
v8::HandleScope scope(env->isolate());
4345
auto local = resolver.Get(env->isolate());
4446
v8::Local<v8::Value> exception =
@@ -49,11 +51,6 @@ inline void RejectPromiseWithUVError(
4951
// ---------------------------------------------------------------------------
5052
// MakePromise — Creates a v8::Promise::Resolver, sets the return value
5153
// on `args`, and returns a Global handle for use in the coroutine.
52-
//
53-
// Usage from a binding function:
54-
// auto resolver = MakePromise(env, args);
55-
// auto task = my_coroutine(env, std::move(resolver), ...);
56-
// task.Start();
5754
// ---------------------------------------------------------------------------
5855

5956
inline v8::Global<v8::Promise::Resolver> MakePromise(

0 commit comments

Comments
 (0)