59546a835ef70065481e833df533676108893c50
[framework/web/webkit-efl.git] / Source / JavaScriptCore / heap / HeapTimer.cpp
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "HeapTimer.h"
28
29 #include "APIShims.h"
30 #include "JSObject.h"
31 #include "JSString.h"
32 #include "ScopeChain.h"
33 #include <wtf/Threading.h>
34
35 namespace JSC {
36
37 #if USE(CF)
38     
39 const CFTimeInterval HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
40
41 HeapTimer::HeapTimer(JSGlobalData* globalData, CFRunLoopRef runLoop)
42     : m_globalData(globalData)
43     , m_runLoop(runLoop)
44 {
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);
49 }
50
51 HeapTimer::~HeapTimer()
52 {
53     CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
54     CFRunLoopTimerInvalidate(m_timer.get());
55 }
56
57 void HeapTimer::synchronize()
58 {
59     if (CFRunLoopGetCurrent() == m_runLoop.get())
60         return;
61     CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
62     m_runLoop = CFRunLoopGetCurrent();
63     CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
64 }
65
66 void HeapTimer::invalidate()
67 {
68     m_globalData = 0;
69     CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() - s_decade);
70 }
71
72 void HeapTimer::didStartVMShutdown()
73 {
74     if (CFRunLoopGetCurrent() == m_runLoop.get()) {
75         invalidate();
76         delete this;
77         return;
78     }
79     ASSERT(!m_globalData->apiLock().currentThreadIsHoldingLock());
80     MutexLocker locker(m_shutdownMutex);
81     invalidate();
82 }
83
84 void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info)
85 {
86     HeapTimer* agent = static_cast<HeapTimer*>(info);
87     agent->m_shutdownMutex.lock();
88     if (!agent->m_globalData) {
89         agent->m_shutdownMutex.unlock();
90         delete agent;
91         return;
92     }
93     {
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);
96         agent->doWork();
97     }
98     agent->m_shutdownMutex.unlock();
99 }
100
101 #elif PLATFORM(BLACKBERRY)
102
103 HeapTimer::HeapTimer(JSGlobalData* globalData)
104     : m_globalData(globalData)
105     , m_timer(this, &HeapTimer::timerDidFire)
106 {
107 }
108
109 HeapTimer::~HeapTimer()
110 {
111 }
112
113 void HeapTimer::timerDidFire()
114 {
115     doWork();
116 }
117
118 void HeapTimer::synchronize()
119 {
120 }
121
122 void HeapTimer::invalidate()
123 {
124 }
125
126 void HeapTimer::didStartVMShutdown()
127 {
128     delete this;
129 }
130
131 #elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK)
132
133 HeapTimer::HeapTimer(JSGlobalData* globalData)
134     : m_globalData(globalData)
135 {
136     ecore_init();
137 }
138
139 HeapTimer::~HeapTimer()
140 {
141     stop();
142     ecore_shutdown();
143 }
144
145 void HeapTimer::didStartVMShutdown()
146 {
147     delete this;
148 }
149
150 void HeapTimer::synchronize()
151 {
152 }
153
154 void HeapTimer::invalidate()
155 {
156 }
157
158 bool HeapTimer::timerDidFire(void* info)
159 {
160     HeapTimer* agent = static_cast<HeapTimer*>(info);
161     agent->doWork();
162
163     return ECORE_CALLBACK_CANCEL;
164 }
165
166 #else
167
168 HeapTimer::HeapTimer(JSGlobalData* globalData)
169     : m_globalData(globalData)
170 {
171 }
172
173 HeapTimer::~HeapTimer()
174 {
175 }
176
177 void HeapTimer::didStartVMShutdown()
178 {
179     delete this;
180 }
181
182 void HeapTimer::synchronize()
183 {
184 }
185
186 void HeapTimer::invalidate()
187 {
188 }
189
190 #endif
191     
192
193 } // namespace JSC