diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/Watchdog.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/Watchdog.h | 89 |
1 files changed, 37 insertions, 52 deletions
diff --git a/Source/JavaScriptCore/runtime/Watchdog.h b/Source/JavaScriptCore/runtime/Watchdog.h index a7b29ef7a..01a869748 100644 --- a/Source/JavaScriptCore/runtime/Watchdog.h +++ b/Source/JavaScriptCore/runtime/Watchdog.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,91 +26,76 @@ #ifndef Watchdog_h #define Watchdog_h -#if PLATFORM(MAC) || PLATFORM(IOS) -#include <dispatch/dispatch.h> -#endif +#include <wtf/Lock.h> +#include <wtf/Ref.h> +#include <wtf/ThreadSafeRefCounted.h> +#include <wtf/WorkQueue.h> namespace JSC { class ExecState; class VM; -class Watchdog { +class Watchdog : public WTF::ThreadSafeRefCounted<Watchdog> { + WTF_MAKE_FAST_ALLOCATED; public: class Scope; Watchdog(); - ~Watchdog(); typedef bool (*ShouldTerminateCallback)(ExecState*, void* data1, void* data2); - void setTimeLimit(VM&, double seconds, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0); + void setTimeLimit(std::chrono::microseconds limit, ShouldTerminateCallback = 0, void* data1 = 0, void* data2 = 0); + JS_EXPORT_PRIVATE void terminateSoon(); - // This version of didFire() will check the elapsed CPU time and call the - // callback (if needed) to determine if the watchdog should fire. - bool didFire(ExecState*); + bool shouldTerminate(ExecState* exec) + { + if (!m_timerDidFire) + return false; + return shouldTerminateSlow(exec); + } - bool isEnabled(); - - // This version of didFire() is a more efficient version for when we want - // to know if the watchdog has fired in the past, and not whether it should - // fire right now. - bool didFire() { return m_didFire; } - void fire(); + bool hasTimeLimit(); + void enteredVM(); + void exitedVM(); void* timerDidFireAddress() { return &m_timerDidFire; } + static const std::chrono::microseconds noTimeLimit; + private: - void arm(); - void disarm(); - void startCountdownIfNeeded(); - void startCountdown(double limit); - void stopCountdown(); - bool isArmed() { return !!m_reentryCount; } - - // Platform specific timer implementation: - void initTimer(); - void destroyTimer(); - void startTimer(double limit); - void stopTimer(); - - // m_timerDidFire (above) indicates whether the timer fired. The Watchdog + void startTimer(LockHolder&, std::chrono::microseconds timeLimit); + void stopTimer(LockHolder&); + + bool shouldTerminateSlow(ExecState*); + + // m_timerDidFire indicates whether the timer fired. The Watchdog // still needs to check if the allowed CPU time has elapsed. If so, then // the Watchdog fires and m_didFire will be set. // NOTE: m_timerDidFire is only set by the platform specific timer // (probably from another thread) but is only cleared in the script thread. bool m_timerDidFire; - bool m_didFire; - // All time units are in seconds. - double m_limit; - double m_startTime; - double m_elapsedTime; + std::chrono::microseconds m_timeLimit; + + std::chrono::microseconds m_cpuDeadline; + std::chrono::microseconds m_wallClockDeadline; + + // Writes to m_timerDidFire and m_timeLimit, and Reads+Writes to m_cpuDeadline and m_wallClockDeadline + // must be guarded by this lock. + Lock m_lock; - int m_reentryCount; - bool m_isStopped; + bool m_hasEnteredVM { false }; ShouldTerminateCallback m_callback; void* m_callbackData1; void* m_callbackData2; -#if PLATFORM(MAC) || PLATFORM(IOS) - dispatch_queue_t m_queue; - dispatch_source_t m_timer; -#endif + Ref<WorkQueue> m_timerQueue; + std::function<void ()> m_timerHandler; - friend class Watchdog::Scope; friend class LLIntOffsetsExtractor; }; -class Watchdog::Scope { -public: - Scope(Watchdog&); - ~Scope(); - -private: - Watchdog& m_watchdog; -}; - } // namespace JSC #endif // Watchdog_h |