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_LOCKER_H_
0006 #define INCLUDE_V8_LOCKER_H_
0007 
0008 #include "v8config.h"  // NOLINT(build/include_directory)
0009 
0010 namespace v8 {
0011 
0012 namespace internal {
0013 class Isolate;
0014 }  // namespace internal
0015 
0016 class Isolate;
0017 
0018 /**
0019  * Multiple threads in V8 are allowed, but only one thread at a time is allowed
0020  * to use any given V8 isolate, see the comments in the Isolate class. The
0021  * definition of 'using a V8 isolate' includes accessing handles or holding onto
0022  * object pointers obtained from V8 handles while in the particular V8 isolate.
0023  * It is up to the user of V8 to ensure, perhaps with locking, that this
0024  * constraint is not violated. In addition to any other synchronization
0025  * mechanism that may be used, the v8::Locker and v8::Unlocker classes must be
0026  * used to signal thread switches to V8.
0027  *
0028  * v8::Locker is a scoped lock object. While it's active, i.e. between its
0029  * construction and destruction, the current thread is allowed to use the locked
0030  * isolate. V8 guarantees that an isolate can be locked by at most one thread at
0031  * any time. In other words, the scope of a v8::Locker is a critical section.
0032  *
0033  * Sample usage:
0034  * \code
0035  * ...
0036  * {
0037  *   v8::Locker locker(isolate);
0038  *   v8::Isolate::Scope isolate_scope(isolate);
0039  *   ...
0040  *   // Code using V8 and isolate goes here.
0041  *   ...
0042  * } // Destructor called here
0043  * \endcode
0044  *
0045  * If you wish to stop using V8 in a thread A you can do this either by
0046  * destroying the v8::Locker object as above or by constructing a v8::Unlocker
0047  * object:
0048  *
0049  * \code
0050  * {
0051  *   isolate->Exit();
0052  *   v8::Unlocker unlocker(isolate);
0053  *   ...
0054  *   // Code not using V8 goes here while V8 can run in another thread.
0055  *   ...
0056  * } // Destructor called here.
0057  * isolate->Enter();
0058  * \endcode
0059  *
0060  * The Unlocker object is intended for use in a long-running callback from V8,
0061  * where you want to release the V8 lock for other threads to use.
0062  *
0063  * The v8::Locker is a recursive lock, i.e. you can lock more than once in a
0064  * given thread. This can be useful if you have code that can be called either
0065  * from code that holds the lock or from code that does not. The Unlocker is
0066  * not recursive so you can not have several Unlockers on the stack at once, and
0067  * you cannot use an Unlocker in a thread that is not inside a Locker's scope.
0068  *
0069  * An unlocker will unlock several lockers if it has to and reinstate the
0070  * correct depth of locking on its destruction, e.g.:
0071  *
0072  * \code
0073  * // V8 not locked.
0074  * {
0075  *   v8::Locker locker(isolate);
0076  *   Isolate::Scope isolate_scope(isolate);
0077  *   // V8 locked.
0078  *   {
0079  *     v8::Locker another_locker(isolate);
0080  *     // V8 still locked (2 levels).
0081  *     {
0082  *       isolate->Exit();
0083  *       v8::Unlocker unlocker(isolate);
0084  *       // V8 not locked.
0085  *     }
0086  *     isolate->Enter();
0087  *     // V8 locked again (2 levels).
0088  *   }
0089  *   // V8 still locked (1 level).
0090  * }
0091  * // V8 Now no longer locked.
0092  * \endcode
0093  */
0094 class V8_EXPORT Unlocker {
0095  public:
0096   /**
0097    * Initialize Unlocker for a given Isolate.
0098    */
0099   V8_INLINE explicit Unlocker(Isolate* isolate) { Initialize(isolate); }
0100 
0101   ~Unlocker();
0102 
0103  private:
0104   void Initialize(Isolate* isolate);
0105 
0106   internal::Isolate* isolate_;
0107 };
0108 
0109 class V8_EXPORT Locker {
0110  public:
0111   /**
0112    * Initialize Locker for a given Isolate.
0113    */
0114   V8_INLINE explicit Locker(Isolate* isolate) { Initialize(isolate); }
0115 
0116   ~Locker();
0117 
0118   /**
0119    * Returns whether or not the locker for a given isolate, is locked by the
0120    * current thread.
0121    */
0122   static bool IsLocked(Isolate* isolate);
0123 
0124   // Disallow copying and assigning.
0125   Locker(const Locker&) = delete;
0126   void operator=(const Locker&) = delete;
0127 
0128  private:
0129   void Initialize(Isolate* isolate);
0130 
0131   bool has_lock_;
0132   bool top_level_;
0133   internal::Isolate* isolate_;
0134 };
0135 
0136 }  // namespace v8
0137 
0138 #endif  // INCLUDE_V8_LOCKER_H_