2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "HeapTimer.h"
32 #include "ScopeChain.h"
33 #include <wtf/Threading.h>
39 const CFTimeInterval HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
41 HeapTimer::HeapTimer(JSGlobalData* globalData, CFRunLoopRef runLoop)
42 : m_globalData(globalData)
45 memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
46 m_context.info = this;
47 m_timer.adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
48 CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
51 HeapTimer::~HeapTimer()
53 CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
54 CFRunLoopTimerInvalidate(m_timer.get());
57 void HeapTimer::synchronize()
59 if (CFRunLoopGetCurrent() == m_runLoop.get())
61 CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
62 m_runLoop = CFRunLoopGetCurrent();
63 CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
66 void HeapTimer::invalidate()
69 CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() - s_decade);
72 void HeapTimer::didStartVMShutdown()
74 if (CFRunLoopGetCurrent() == m_runLoop.get()) {
79 ASSERT(!m_globalData->apiLock().currentThreadIsHoldingLock());
80 MutexLocker locker(m_shutdownMutex);
84 void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info)
86 HeapTimer* agent = static_cast<HeapTimer*>(info);
87 agent->m_shutdownMutex.lock();
88 if (!agent->m_globalData) {
89 agent->m_shutdownMutex.unlock();
94 // We don't ref here to prevent us from resurrecting the ref count of a "dead" JSGlobalData.
95 APIEntryShim shim(agent->m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
98 agent->m_shutdownMutex.unlock();
101 #elif PLATFORM(BLACKBERRY)
103 HeapTimer::HeapTimer(JSGlobalData* globalData)
104 : m_globalData(globalData)
105 , m_timer(this, &HeapTimer::timerDidFire)
109 HeapTimer::~HeapTimer()
113 void HeapTimer::timerDidFire()
118 void HeapTimer::synchronize()
122 void HeapTimer::invalidate()
126 void HeapTimer::didStartVMShutdown()
131 #elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK)
133 HeapTimer::HeapTimer(JSGlobalData* globalData)
134 : m_globalData(globalData)
139 HeapTimer::~HeapTimer()
145 void HeapTimer::didStartVMShutdown()
150 void HeapTimer::synchronize()
154 void HeapTimer::invalidate()
158 bool HeapTimer::timerDidFire(void* info)
160 HeapTimer* agent = static_cast<HeapTimer*>(info);
163 return ECORE_CALLBACK_CANCEL;
168 HeapTimer::HeapTimer(JSGlobalData* globalData)
169 : m_globalData(globalData)
173 HeapTimer::~HeapTimer()
177 void HeapTimer::didStartVMShutdown()
182 void HeapTimer::synchronize()
186 void HeapTimer::invalidate()