| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d9084d2 commit d601a0a
12 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -87,7 +87,7 @@ struct AsyncWrapObject : public AsyncWrap { | |||
| 87 | 87 | SET_SELF_SIZE(AsyncWrapObject) | |
| 88 | 88 | }; | |
| 89 | 89 | ||
| 90 | - void AsyncWrap::DestroyAsyncIdsCallback(Environment* env, void* data) { | ||
| 90 | + void AsyncWrap::DestroyAsyncIdsCallback(Environment* env) { | ||
| 91 | 91 | Local<Function> fn = env->async_hooks_destroy_function(); | |
| 92 | 92 | ||
| 93 | 93 | TryCatchScope try_catch(env, TryCatchScope::CatchMode::kFatal); | |
@@ -642,7 +642,7 @@ void AsyncWrap::EmitDestroy(Environment* env, double async_id) { | |||
| 642 | 642 | } | |
| 643 | 643 | ||
| 644 | 644 | if (env->destroy_async_id_list()->empty()) { | |
| 645 | - env->SetUnrefImmediate(DestroyAsyncIdsCallback, nullptr); | ||
| 645 | + env->SetUnrefImmediate(&DestroyAsyncIdsCallback); | ||
| 646 | 646 | } | |
| 647 | 647 | ||
| 648 | 648 | env->destroy_async_id_list()->push_back(async_id); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -154,7 +154,7 @@ class AsyncWrap : public BaseObject { | |||
| 154 | 154 | static void EmitTraceEventAfter(ProviderType type, double async_id); | |
| 155 | 155 | void EmitTraceEventDestroy(); | |
| 156 | 156 | ||
| 157 | - static void DestroyAsyncIdsCallback(Environment* env, void* data); | ||
| 157 | + static void DestroyAsyncIdsCallback(Environment* env); | ||
| 158 | 158 | ||
| 159 | 159 | inline ProviderType provider_type() const; | |
| 160 | 160 | inline ProviderType set_provider_type(ProviderType provider); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -690,9 +690,9 @@ class QueryWrap : public AsyncWrap { | |||
| 690 | 690 | } | |
| 691 | 691 | ||
| 692 | 692 | void QueueResponseCallback(int status) { | |
| 693 | - env()->SetImmediate([](Environment*, void* data) { | ||
| 694 | - static_cast<QueryWrap*>(data)->AfterResponse(); | ||
| 695 | - }, this, object()); | ||
| 693 | + env()->SetImmediate([this](Environment*) { | ||
| 694 | + AfterResponse(); | ||
| 695 | + }, object()); | ||
| 696 | 696 | ||
| 697 | 697 | channel_->set_query_last_ok(status != ARES_ECONNREFUSED); | |
| 698 | 698 | channel_->ModifyActivityQueryCount(-1); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -753,33 +753,66 @@ inline void IsolateData::set_options( | |||
| 753 | 753 | options_ = std::move(options); | |
| 754 | 754 | } | |
| 755 | 755 | ||
| 756 | - void Environment::CreateImmediate(native_immediate_callback cb, | ||
| 757 | - void* data, | ||
| 758 | - v8::Local<v8::Object> obj, | ||
| 756 | + template <typename Fn> | ||
| 757 | + void Environment::CreateImmediate(Fn&& cb, | ||
| 758 | + v8::Local<v8::Object> keep_alive, | ||
| 759 | 759 | bool ref) { | |
| 760 | - native_immediate_callbacks_.push_back({ | ||
| 761 | - cb, | ||
| 762 | - data, | ||
| 763 | - v8::Global<v8::Object>(isolate_, obj), | ||
| 764 | - ref | ||
| 765 | - }); | ||
| 760 | + auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>( | ||
| 761 | + std::move(cb), | ||
| 762 | + v8::Global<v8::Object>(isolate(), keep_alive), | ||
| 763 | + ref); | ||
| 764 | + NativeImmediateCallback* prev_tail = native_immediate_callbacks_tail_; | ||
| 765 | + | ||
| 766 | + native_immediate_callbacks_tail_ = callback.get(); | ||
| 767 | + if (prev_tail != nullptr) | ||
| 768 | + prev_tail->set_next(std::move(callback)); | ||
| 769 | + else | ||
| 770 | + native_immediate_callbacks_head_ = std::move(callback); | ||
| 771 | + | ||
| 766 | 772 | immediate_info()->count_inc(1); | |
| 767 | 773 | } | |
| 768 | 774 | ||
| 769 | - void Environment::SetImmediate(native_immediate_callback cb, | ||
| 770 | - void* data, | ||
| 771 | - v8::Local<v8::Object> obj) { | ||
| 772 | - CreateImmediate(cb, data, obj, true); | ||
| 775 | + template <typename Fn> | ||
| 776 | + void Environment::SetImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { | ||
| 777 | + CreateImmediate(std::move(cb), keep_alive, true); | ||
| 773 | 778 | ||
| 774 | 779 | if (immediate_info()->ref_count() == 0) | |
| 775 | 780 | ToggleImmediateRef(true); | |
| 776 | 781 | immediate_info()->ref_count_inc(1); | |
| 777 | 782 | } | |
| 778 | 783 | ||
| 779 | - void Environment::SetUnrefImmediate(native_immediate_callback cb, | ||
| 780 | - void* data, | ||
| 781 | - v8::Local<v8::Object> obj) { | ||
| 782 | - CreateImmediate(cb, data, obj, false); | ||
| 784 | + template <typename Fn> | ||
| 785 | + void Environment::SetUnrefImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { | ||
| 786 | + CreateImmediate(std::move(cb), keep_alive, false); | ||
| 787 | + } | ||
| 788 | + | ||
| 789 | + Environment::NativeImmediateCallback::NativeImmediateCallback(bool refed) | ||
| 790 | + : refed_(refed) {} | ||
| 791 | + | ||
| 792 | + bool Environment::NativeImmediateCallback::is_refed() const { | ||
| 793 | + return refed_; | ||
| 794 | + } | ||
| 795 | + | ||
| 796 | + std::unique_ptr<Environment::NativeImmediateCallback> | ||
| 797 | + Environment::NativeImmediateCallback::get_next() { | ||
| 798 | + return std::move(next_); | ||
| 799 | + } | ||
| 800 | + | ||
| 801 | + void Environment::NativeImmediateCallback::set_next( | ||
| 802 | + std::unique_ptr<NativeImmediateCallback> next) { | ||
| 803 | + next_ = std::move(next); | ||
| 804 | + } | ||
| 805 | + | ||
| 806 | + template <typename Fn> | ||
| 807 | + Environment::NativeImmediateCallbackImpl<Fn>::NativeImmediateCallbackImpl( | ||
| 808 | + Fn&& callback, v8::Global<v8::Object>&& keep_alive, bool refed) | ||
| 809 | + : NativeImmediateCallback(refed), | ||
| 810 | + callback_(std::move(callback)), | ||
| 811 | + keep_alive_(std::move(keep_alive)) {} | ||
| 812 | + | ||
| 813 | + template <typename Fn> | ||
| 814 | + void Environment::NativeImmediateCallbackImpl<Fn>::Call(Environment* env) { | ||
| 815 | + callback_(env); | ||
| 783 | 816 | } | |
| 784 | 817 | ||
| 785 | 818 | inline bool Environment::can_call_into_js() const { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -339,7 +339,7 @@ Environment::Environment(IsolateData* isolate_data, | |||
| 339 | 339 | [](void* arg) { | |
| 340 | 340 | Environment* env = static_cast<Environment*>(arg); | |
| 341 | 341 | if (!env->destroy_async_id_list()->empty()) | |
| 342 | - AsyncWrap::DestroyAsyncIdsCallback(env, nullptr); | ||
| 342 | + AsyncWrap::DestroyAsyncIdsCallback(env); | ||
| 343 | 343 | }, | |
| 344 | 344 | this); | |
| 345 | 345 | ||
@@ -642,42 +642,38 @@ void Environment::AtExit(void (*cb)(void* arg), void* arg) { | |||
| 642 | 642 | void Environment::RunAndClearNativeImmediates() { | |
| 643 | 643 | TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment), | |
| 644 | 644 | "RunAndClearNativeImmediates", this); | |
| 645 | - size_t count = native_immediate_callbacks_.size(); | ||
| 646 | - if (count > 0) { | ||
| 647 | - size_t ref_count = 0; | ||
| 648 | - std::vector<NativeImmediateCallback> list; | ||
| 649 | - native_immediate_callbacks_.swap(list); | ||
| 650 | - auto drain_list = [&]() { | ||
| 651 | - TryCatchScope try_catch(this); | ||
| 652 | - for (auto it = list.begin(); it != list.end(); ++it) { | ||
| 653 | - DebugSealHandleScope seal_handle_scope(isolate()); | ||
| 654 | - it->cb_(this, it->data_); | ||
| 655 | - if (it->refed_) | ||
| 656 | - ref_count++; | ||
| 657 | - if (UNLIKELY(try_catch.HasCaught())) { | ||
| 658 | - if (!try_catch.HasTerminated()) | ||
| 659 | - errors::TriggerUncaughtException(isolate(), try_catch); | ||
| 660 | - | ||
| 661 | - // We are done with the current callback. Increase the counter so that | ||
| 662 | - // the steps below make everything *after* the current item part of | ||
| 663 | - // the new list. | ||
| 664 | - it++; | ||
| 665 | - | ||
| 666 | - // Bail out, remove the already executed callbacks from list | ||
| 667 | - // and set up a new TryCatch for the other pending callbacks. | ||
| 668 | - std::move_backward(it, list.end(), list.begin() + (list.end() - it)); | ||
| 669 | - list.resize(list.end() - it); | ||
| 670 | - return true; | ||
| 671 | - } | ||
| 645 | + size_t ref_count = 0; | ||
| 646 | + size_t count = 0; | ||
| 647 | + std::unique_ptr<NativeImmediateCallback> head; | ||
| 648 | + head.swap(native_immediate_callbacks_head_); | ||
| 649 | + native_immediate_callbacks_tail_ = nullptr; | ||
| 650 | + | ||
| 651 | + auto drain_list = [&]() { | ||
| 652 | + TryCatchScope try_catch(this); | ||
| 653 | + for (; head; head = head->get_next()) { | ||
| 654 | + DebugSealHandleScope seal_handle_scope(isolate()); | ||
| 655 | + count++; | ||
| 656 | + if (head->is_refed()) | ||
| 657 | + ref_count++; | ||
| 658 | + | ||
| 659 | + head->Call(this); | ||
| 660 | + if (UNLIKELY(try_catch.HasCaught())) { | ||
| 661 | + if (!try_catch.HasTerminated()) | ||
| 662 | + errors::TriggerUncaughtException(isolate(), try_catch); | ||
| 663 | + | ||
| 664 | + // We are done with the current callback. Move one iteration along, | ||
| 665 | + // as if we had completed successfully. | ||
| 666 | + head = head->get_next(); | ||
| 667 | + return true; | ||
| 672 | 668 | } | |
| 673 | - return false; | ||
| 674 | - }; | ||
| 675 | - while (drain_list()) {} | ||
| 669 | + } | ||
| 670 | + return false; | ||
| 671 | + }; | ||
| 672 | + while (head && drain_list()) {} | ||
| 676 | 673 | ||
| 677 | - DCHECK_GE(immediate_info()->count(), count); | ||
| 678 | - immediate_info()->count_dec(count); | ||
| 679 | - immediate_info()->ref_count_dec(ref_count); | ||
| 680 | - } | ||
| 674 | + DCHECK_GE(immediate_info()->count(), count); | ||
| 675 | + immediate_info()->count_dec(count); | ||
| 676 | + immediate_info()->ref_count_dec(ref_count); | ||
| 681 | 677 | } | |
| 682 | 678 | ||
| 683 | 679 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1153,15 +1153,15 @@ class Environment : public MemoryRetainer { | |||
| 1153 | 1153 | return current_value; | |
| 1154 | 1154 | } | |
| 1155 | 1155 | ||
| 1156 | - typedef void (*native_immediate_callback)(Environment* env, void* data); | ||
| 1157 | - // cb will be called as cb(env, data) on the next event loop iteration. | ||
| 1158 | - // obj will be kept alive between now and after the callback has run. | ||
| 1159 | - inline void SetImmediate(native_immediate_callback cb, | ||
| 1160 | - void* data, | ||
| 1161 | - v8::Local<v8::Object> obj = v8::Local<v8::Object>()); | ||
| 1162 | - inline void SetUnrefImmediate(native_immediate_callback cb, | ||
| 1163 | - void* data, | ||
| 1164 | - v8::Local<v8::Object> obj = | ||
| 1156 | + // cb will be called as cb(env) on the next event loop iteration. | ||
| 1157 | + // keep_alive will be kept alive between now and after the callback has run. | ||
| 1158 | + template <typename Fn> | ||
| 1159 | + inline void SetImmediate(Fn&& cb, | ||
| 1160 | + v8::Local<v8::Object> keep_alive = | ||
| 1161 | + v8::Local<v8::Object>()); | ||
| 1162 | + template <typename Fn> | ||
| 1163 | + inline void SetUnrefImmediate(Fn&& cb, | ||
| 1164 | + v8::Local<v8::Object> keep_alive = | ||
| 1165 | 1165 | v8::Local<v8::Object>()); | |
| 1166 | 1166 | // This needs to be available for the JS-land setImmediate(). | |
| 1167 | 1167 | void ToggleImmediateRef(bool ref); | |
@@ -1226,9 +1226,9 @@ class Environment : public MemoryRetainer { | |||
| 1226 | 1226 | #endif // HAVE_INSPECTOR | |
| 1227 | 1227 | ||
| 1228 | 1228 | private: | |
| 1229 | - inline void CreateImmediate(native_immediate_callback cb, | ||
| 1230 | - void* data, | ||
| 1231 | - v8::Local<v8::Object> obj, | ||
| 1229 | + template <typename Fn> | ||
| 1230 | + inline void CreateImmediate(Fn&& cb, | ||
| 1231 | + v8::Local<v8::Object> keep_alive, | ||
| 1232 | 1232 | bool ref); | |
| 1233 | 1233 | ||
| 1234 | 1234 | inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), | |
@@ -1352,13 +1352,38 @@ class Environment : public MemoryRetainer { | |||
| 1352 | 1352 | ||
| 1353 | 1353 | std::list<ExitCallback> at_exit_functions_; | |
| 1354 | 1354 | ||
| 1355 | - struct NativeImmediateCallback { | ||
| 1356 | - native_immediate_callback cb_; | ||
| 1357 | - void* data_; | ||
| 1358 | - v8::Global<v8::Object> keep_alive_; | ||
| 1355 | + class NativeImmediateCallback { | ||
| 1356 | + public: | ||
| 1357 | + explicit inline NativeImmediateCallback(bool refed); | ||
| 1358 | + | ||
| 1359 | + virtual ~NativeImmediateCallback() = default; | ||
| 1360 | + virtual void Call(Environment* env) = 0; | ||
| 1361 | + | ||
| 1362 | + inline bool is_refed() const; | ||
| 1363 | + inline std::unique_ptr<NativeImmediateCallback> get_next(); | ||
| 1364 | + inline void set_next(std::unique_ptr<NativeImmediateCallback> next); | ||
| 1365 | + | ||
| 1366 | + private: | ||
| 1359 | 1367 | bool refed_; | |
| 1368 | + std::unique_ptr<NativeImmediateCallback> next_; | ||
| 1369 | + }; | ||
| 1370 | + | ||
| 1371 | + template <typename Fn> | ||
| 1372 | + class NativeImmediateCallbackImpl final : public NativeImmediateCallback { | ||
| 1373 | + public: | ||
| 1374 | + NativeImmediateCallbackImpl(Fn&& callback, | ||
| 1375 | + v8::Global<v8::Object>&& keep_alive, | ||
| 1376 | + bool refed); | ||
| 1377 | + void Call(Environment* env) override; | ||
| 1378 | + | ||
| 1379 | + private: | ||
| 1380 | + Fn callback_; | ||
| 1381 | + v8::Global<v8::Object> keep_alive_; | ||
| 1360 | 1382 | }; | |
| 1361 | - std::vector<NativeImmediateCallback> native_immediate_callbacks_; | ||
| 1383 | + | ||
| 1384 | + std::unique_ptr<NativeImmediateCallback> native_immediate_callbacks_head_; | ||
| 1385 | + NativeImmediateCallback* native_immediate_callbacks_tail_ = nullptr; | ||
| 1386 | + | ||
| 1362 | 1387 | void RunAndClearNativeImmediates(); | |
| 1363 | 1388 | static void CheckImmediate(uv_check_t* handle); | |
| 1364 | 1389 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,27 +36,33 @@ class BufferFinalizer : private Finalizer { | |||
| 36 | 36 | public: | |
| 37 | 37 | // node::Buffer::FreeCallback | |
| 38 | 38 | static void FinalizeBufferCallback(char* data, void* hint) { | |
| 39 | - BufferFinalizer* finalizer = static_cast<BufferFinalizer*>(hint); | ||
| 39 | + std::unique_ptr<BufferFinalizer, Deleter> finalizer{ | ||
| 40 | + static_cast<BufferFinalizer*>(hint)}; | ||
| 40 | 41 | finalizer->_finalize_data = data; | |
| 41 | - static_cast<node_napi_env>(finalizer->_env)->node_env() | ||
| 42 | - ->SetImmediate([](node::Environment* env, void* hint) { | ||
| 43 | - BufferFinalizer* finalizer = static_cast<BufferFinalizer*>(hint); | ||
| 44 | - | ||
| 45 | - if (finalizer->_finalize_callback != nullptr) { | ||
| 46 | - v8::HandleScope handle_scope(finalizer->_env->isolate); | ||
| 47 | - v8::Context::Scope context_scope(finalizer->_env->context()); | ||
| 48 | - | ||
| 49 | - finalizer->_env->CallIntoModuleThrow([&](napi_env env) { | ||
| 50 | - finalizer->_finalize_callback( | ||
| 51 | - env, | ||
| 52 | - finalizer->_finalize_data, | ||
| 53 | - finalizer->_finalize_hint); | ||
| 54 | - }); | ||
| 55 | - } | ||
| 56 | 42 | ||
| 57 | - Delete(finalizer); | ||
| 58 | - }, hint); | ||
| 43 | + node::Environment* node_env = | ||
| 44 | + static_cast<node_napi_env>(finalizer->_env)->node_env(); | ||
| 45 | + node_env->SetImmediate( | ||
| 46 | + [finalizer = std::move(finalizer)](node::Environment* env) { | ||
| 47 | + if (finalizer->_finalize_callback == nullptr) return; | ||
| 48 | + | ||
| 49 | + v8::HandleScope handle_scope(finalizer->_env->isolate); | ||
| 50 | + v8::Context::Scope context_scope(finalizer->_env->context()); | ||
| 51 | + | ||
| 52 | + finalizer->_env->CallIntoModuleThrow([&](napi_env env) { | ||
| 53 | + finalizer->_finalize_callback( | ||
| 54 | + env, | ||
| 55 | + finalizer->_finalize_data, | ||
| 56 | + finalizer->_finalize_hint); | ||
| 57 | + }); | ||
| 58 | + }); | ||
| 59 | 59 | } | |
| 60 | + | ||
| 61 | + struct Deleter { | ||
| 62 | + void operator()(BufferFinalizer* finalizer) { | ||
| 63 | + Finalizer::Delete(finalizer); | ||
| 64 | + } | ||
| 65 | + }; | ||
| 60 | 66 | }; | |
| 61 | 67 | ||
| 62 | 68 | static inline napi_env NewEnv(v8::Local<v8::Context> context) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -170,35 +170,33 @@ inline void FileHandle::Close() { | |||
| 170 | 170 | ||
| 171 | 171 | struct err_detail { int ret; int fd; }; | |
| 172 | 172 | ||
| 173 | - err_detail* detail = new err_detail { ret, fd_ }; | ||
| 173 | + err_detail detail { ret, fd_ }; | ||
| 174 | 174 | ||
| 175 | 175 | if (ret < 0) { | |
| 176 | 176 | // Do not unref this | |
| 177 | - env()->SetImmediate([](Environment* env, void* data) { | ||
| 177 | + env()->SetImmediate([detail](Environment* env) { | ||
| 178 | 178 | char msg[70]; | |
| 179 | - std::unique_ptr<err_detail> detail(static_cast<err_detail*>(data)); | ||
| 180 | 179 | snprintf(msg, arraysize(msg), | |
| 181 | 180 | "Closing file descriptor %d on garbage collection failed", | |
| 182 | - detail->fd); | ||
| 181 | + detail.fd); | ||
| 183 | 182 | // This exception will end up being fatal for the process because | |
| 184 | 183 | // it is being thrown from within the SetImmediate handler and | |
| 185 | 184 | // there is no JS stack to bubble it to. In other words, tearing | |
| 186 | 185 | // down the process is the only reasonable thing we can do here. | |
| 187 | 186 | HandleScope handle_scope(env->isolate()); | |
| 188 | - env->ThrowUVException(detail->ret, "close", msg); | ||
| 189 | - }, detail); | ||
| 187 | + env->ThrowUVException(detail.ret, "close", msg); | ||
| 188 | + }); | ||
| 190 | 189 | return; | |
| 191 | 190 | } | |
| 192 | 191 | ||
| 193 | 192 | // If the close was successful, we still want to emit a process warning | |
| 194 | 193 | // to notify that the file descriptor was gc'd. We want to be noisy about | |
| 195 | 194 | // this because not explicitly closing the FileHandle is a bug. | |
| 196 | - env()->SetUnrefImmediate([](Environment* env, void* data) { | ||
| 197 | - std::unique_ptr<err_detail> detail(static_cast<err_detail*>(data)); | ||
| 195 | + env()->SetUnrefImmediate([detail](Environment* env) { | ||
| 198 | 196 | ProcessEmitWarning(env, | |
| 199 | 197 | "Closing file descriptor %d on garbage collection", | |
| 200 | - detail->fd); | ||
| 201 | - }, detail); | ||
| 198 | + detail.fd); | ||
| 199 | + }); | ||
| 202 | 200 | } | |
| 203 | 201 | ||
| 204 | 202 | void FileHandle::CloseReq::Resolve() { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments