Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:05:25

0001 // Copyright 2021 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_V8_MICROTASKS_QUEUE_H_
0006 #define INCLUDE_V8_MICROTASKS_QUEUE_H_
0007 
0008 #include <stddef.h>
0009 
0010 #include <memory>
0011 
0012 #include "v8-local-handle.h"  // NOLINT(build/include_directory)
0013 #include "v8-microtask.h"     // NOLINT(build/include_directory)
0014 #include "v8config.h"         // NOLINT(build/include_directory)
0015 
0016 namespace v8 {
0017 
0018 class Function;
0019 
0020 namespace internal {
0021 class Isolate;
0022 class MicrotaskQueue;
0023 }  // namespace internal
0024 
0025 /**
0026  * Represents the microtask queue, where microtasks are stored and processed.
0027  * https://html.spec.whatwg.org/multipage/webappapis.html#microtask-queue
0028  * https://html.spec.whatwg.org/multipage/webappapis.html#enqueuejob(queuename,-job,-arguments)
0029  * https://html.spec.whatwg.org/multipage/webappapis.html#perform-a-microtask-checkpoint
0030  *
0031  * A MicrotaskQueue instance may be associated to multiple Contexts by passing
0032  * it to Context::New(), and they can be detached by Context::DetachGlobal().
0033  * The embedder must keep the MicrotaskQueue instance alive until all associated
0034  * Contexts are gone or detached.
0035  *
0036  * Use the same instance of MicrotaskQueue for all Contexts that may access each
0037  * other synchronously. E.g. for Web embedding, use the same instance for all
0038  * origins that share the same URL scheme and eTLD+1.
0039  */
0040 class V8_EXPORT MicrotaskQueue {
0041  public:
0042   /**
0043    * Creates an empty MicrotaskQueue instance.
0044    */
0045   static std::unique_ptr<MicrotaskQueue> New(
0046       Isolate* isolate, MicrotasksPolicy policy = MicrotasksPolicy::kAuto);
0047 
0048   virtual ~MicrotaskQueue() = default;
0049 
0050   /**
0051    * Enqueues the callback to the queue.
0052    */
0053   virtual void EnqueueMicrotask(Isolate* isolate,
0054                                 Local<Function> microtask) = 0;
0055 
0056   /**
0057    * Enqueues the callback to the queue.
0058    */
0059   virtual void EnqueueMicrotask(v8::Isolate* isolate,
0060                                 MicrotaskCallback callback,
0061                                 void* data = nullptr) = 0;
0062 
0063   /**
0064    * Adds a callback to notify the embedder after microtasks were run. The
0065    * callback is triggered by explicit RunMicrotasks call or automatic
0066    * microtasks execution (see Isolate::SetMicrotasksPolicy).
0067    *
0068    * Callback will trigger even if microtasks were attempted to run,
0069    * but the microtasks queue was empty and no single microtask was actually
0070    * executed.
0071    *
0072    * Executing scripts inside the callback will not re-trigger microtasks and
0073    * the callback.
0074    */
0075   virtual void AddMicrotasksCompletedCallback(
0076       MicrotasksCompletedCallbackWithData callback, void* data = nullptr) = 0;
0077 
0078   /**
0079    * Removes callback that was installed by AddMicrotasksCompletedCallback.
0080    */
0081   virtual void RemoveMicrotasksCompletedCallback(
0082       MicrotasksCompletedCallbackWithData callback, void* data = nullptr) = 0;
0083 
0084   /**
0085    * Runs microtasks if no microtask is running on this MicrotaskQueue instance.
0086    */
0087   virtual void PerformCheckpoint(Isolate* isolate) = 0;
0088 
0089   /**
0090    * Returns true if a microtask is running on this MicrotaskQueue instance.
0091    */
0092   virtual bool IsRunningMicrotasks() const = 0;
0093 
0094   /**
0095    * Returns the current depth of nested MicrotasksScope that has
0096    * kRunMicrotasks.
0097    */
0098   virtual int GetMicrotasksScopeDepth() const = 0;
0099 
0100   MicrotaskQueue(const MicrotaskQueue&) = delete;
0101   MicrotaskQueue& operator=(const MicrotaskQueue&) = delete;
0102 
0103  private:
0104   friend class internal::MicrotaskQueue;
0105   MicrotaskQueue() = default;
0106 };
0107 
0108 /**
0109  * This scope is used to control microtasks when MicrotasksPolicy::kScoped
0110  * is used on Isolate. In this mode every non-primitive call to V8 should be
0111  * done inside some MicrotasksScope.
0112  * Microtasks are executed when topmost MicrotasksScope marked as kRunMicrotasks
0113  * exits.
0114  * kDoNotRunMicrotasks should be used to annotate calls not intended to trigger
0115  * microtasks.
0116  */
0117 class V8_EXPORT V8_NODISCARD MicrotasksScope {
0118  public:
0119   enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
0120 
0121   V8_DEPRECATE_SOON(
0122       "May be incorrect if context was created with non-default microtask "
0123       "queue")
0124   MicrotasksScope(Isolate* isolate, Type type);
0125 
0126   MicrotasksScope(Local<Context> context, Type type);
0127   MicrotasksScope(Isolate* isolate, MicrotaskQueue* microtask_queue, Type type);
0128   ~MicrotasksScope();
0129 
0130   /**
0131    * Runs microtasks if no kRunMicrotasks scope is currently active.
0132    */
0133   static void PerformCheckpoint(Isolate* isolate);
0134 
0135   /**
0136    * Returns current depth of nested kRunMicrotasks scopes.
0137    */
0138   static int GetCurrentDepth(Isolate* isolate);
0139 
0140   /**
0141    * Returns true while microtasks are being executed.
0142    */
0143   static bool IsRunningMicrotasks(Isolate* isolate);
0144 
0145   // Prevent copying.
0146   MicrotasksScope(const MicrotasksScope&) = delete;
0147   MicrotasksScope& operator=(const MicrotasksScope&) = delete;
0148 
0149  private:
0150   internal::Isolate* const i_isolate_;
0151   internal::MicrotaskQueue* const microtask_queue_;
0152   bool run_;
0153 };
0154 
0155 }  // namespace v8
0156 
0157 #endif  // INCLUDE_V8_MICROTASKS_QUEUE_H_