/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// This file provides classes for encapsulating pieces of data with a check // that ensures the data is only accessed if certain conditions are met. // Checking is only done in debug builds; in release builds these classes // have no space or time overhead. These classes are mainly used for ensuring // that data is used in threadsafe ways. // // ProtectedData does not by itself ensure that data is threadsafe: it only // documents and checks synchronization constraints that need to be established // by the code using the data. If a mutex can be created and directly // associated with the data, consider using the ExclusiveData class instead. // Otherwise, ProtectedData should be used to document whatever synchronization // method is used.
// Protected data checks are enabled in debug builds, except on android where // they cause some permatimeouts in automation. #ifdefined(DEBUG) && !defined(ANDROID) # define JS_HAS_PROTECTED_DATA_CHECKS #endif
// Mark a region of code that should be treated as single threaded and suppress // any ProtectedData checks. // // Note that in practice there may be multiple threads running when this class // is used, due to the presence of multiple runtimes in the process. When each // process has only a single runtime this will no longer be a concern. class MOZ_RAII AutoNoteSingleThreadedRegion { public: #ifdef JS_HAS_PROTECTED_DATA_CHECKS static mozilla::Atomic<size_t, mozilla::SequentiallyConsistent> count;
AutoNoteSingleThreadedRegion() { count++; }
~AutoNoteSingleThreadedRegion() { count--; } #else
AutoNoteSingleThreadedRegion() {} #endif
};
// Class for protected data that may be written to any number of times. Checks // occur when the data is both read from and written to. template <typename Check, typename T> class ProtectedData { using ThisType = ProtectedData<Check, T>;
private:
T value; #ifdef JS_HAS_PROTECTED_DATA_CHECKS
Check check; #endif
};
// Intermediate class for protected data whose checks take no constructor // arguments. template <typename Check, typename T> class ProtectedDataNoCheckArgs : public ProtectedData<Check, T> { using Base = ProtectedData<Check, T>;
// Intermediate class for protected data whose checks take a single argument. template <typename CheckArg, typename Check, typename T> class ProtectedDataWithArg : public ProtectedData<Check, T> { using Base = ProtectedData<Check, T>;
// Data with a no-op check that permits all accesses. This is tantamount to not // using ProtectedData at all, but is in place to document points which need // to be fixed in order for runtimes to be multithreaded (see bug 1323066). template <typename T> using UnprotectedData = ProtectedDataNoCheckArgs<CheckUnprotected, T>;
class CheckThreadLocal { #ifdef JS_HAS_PROTECTED_DATA_CHECKS
ThreadId id;
// Data which may only be accessed by the thread on which it is created. template <typename T> using ThreadData = ProtectedDataNoCheckArgs<CheckThreadLocal, T>;
// Data which belongs to a JSContext and should only be accessed from that // JSContext's thread. Note that a JSContext may not have a thread currently // associated with it and any associated thread may change over time. template <typename T> using ContextData = ProtectedDataContextArg<CheckContextLocal, T>;
template <typename T> using MutexData = ProtectedDataMutexArg<CheckMutexHeld, T>;
// Enum describing which helper threads (GC tasks or Ion compilations) may // access data. enumclass AllowedHelperThread {
None,
GCTask,
IonCompile,
GCTaskOrIonCompile,
};
// Data which may only be accessed by the runtime's main thread. template <typename T> using MainThreadData =
ProtectedDataNoCheckArgs<CheckMainThread<AllowedHelperThread::None>, T>;
// Data which may only be accessed by the runtime's main thread or by various // helper thread tasks. template <typename T> using MainThreadOrGCTaskData =
ProtectedDataNoCheckArgs<CheckMainThread<AllowedHelperThread::GCTask>, T>; template <typename T> using MainThreadOrIonCompileData =
ProtectedDataNoCheckArgs<CheckMainThread<AllowedHelperThread::IonCompile>,
T>; template <typename T> using MainThreadOrGCTaskOrIonCompileData = ProtectedDataNoCheckArgs<
CheckMainThread<AllowedHelperThread::GCTaskOrIonCompile>, T>;
// Runtime wide locks which might protect some data. enumclass GlobalLock { GCLock, HelperThreadLock };
// Data which may only be accessed while holding the GC lock. template <typename T> using GCLockData = ProtectedDataNoCheckArgs<
CheckGlobalLock<GlobalLock::GCLock, AllowedHelperThread::None>, T>;
// Data which may only be accessed while holding the helper thread lock. template <typename T> using HelperThreadLockData = ProtectedDataNoCheckArgs<
CheckGlobalLock<GlobalLock::HelperThreadLock, AllowedHelperThread::None>,
T>;
// Class for protected data that is only written to once. 'const' may sometimes // be usable instead of this class, but in cases where the data cannot be set // to its final value in its constructor this class is helpful. Protected data // checking only occurs when writes are performed, not reads. Steps may need to // be taken to ensure that reads do not occur until the written value is fully // initialized, as such guarantees are not provided by this class. template <typename Check, typename T> class ProtectedDataWriteOnce { using ThisType = ProtectedDataWriteOnce<Check, T>;
T& writeRef() { #ifdef JS_HAS_PROTECTED_DATA_CHECKS if (!AutoNoteSingleThreadedRegion::count) {
check.check();
} // Despite the WriteOnce name, actually allow two writes to accommodate // data that is cleared during teardown.
MOZ_ASSERT(++nwrites <= 2); #endif return value;
}
// Data that is written once with no requirements for exclusive access when // that write occurs. template <typename T> using WriteOnceData = ProtectedDataWriteOnce<CheckUnprotected, T>;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.