12014-08-25 Gavin Barraclough <barraclough@apple.com>
2
3 DOMTimer may be deleted during timer fire
4 https://bugs.webkit.org/show_bug.cgi?id=136198
5
6 Reviewed by NOBODY (OOPS!).
7
8 Consequentially ScheduledActions may also be deleted mid execution.
9 This is fairly surprising & fragile, let's make this simpler.
10
11 Currently DOMTimer instances are effectively owned by the ScriptExecutionContext.
12 There is a 1-1 mapping between timers and contexts, all timers are help in a map
13 on the context and if the context goes away all timers are deleted. Rather than
14 being implemented in a straightforward fashion (a smart pointer type for the map
15 value) this is currently implemented by having the timer objects listen for the
16 context going away using contextDestroyed, and deleting themselves if so.
17
18 Switch to using a smart pointer for values of m_timeouts in ScriptExecutionContext.
19 By using a RefCounted object we can also extend the lifetime of the DOMTimer instance
20 from within the DOMTimer::fired method, so the object is not destroyed while the
21 member function is still on the stack.
22
23 * WebCore.xcodeproj/project.pbxproj:
24 - project -> private since DOMTimer could no longer be a forward declare in ScriptExecutionContext.h.
25 * dom/ScriptExecutionContext.cpp:
26 (WebCore::ScriptExecutionContext::adjustMinimumTimerInterval):
27 (WebCore::ScriptExecutionContext::didChangeTimerAlignmentInterval):
28 - auto* -> auto& since value type in map is no longer a raw pointer.
29 * dom/ScriptExecutionContext.h:
30 (WebCore::ScriptExecutionContext::addTimeout):
31 - DOMTimer* -> PassRefPtr<DOMTimer>
32 * page/DOMTimer.cpp:
33 (WebCore::DOMTimer::DOMTimer):
34 - adopt the initial ref, and pass to addTimeout.
35 (WebCore::DOMTimer::install):
36 - updated comment.
37 (WebCore::DOMTimer::removeById):
38 - instead of explicitly deleting the timer and assuming this will implicitly remove it from the context map,
39 we explicitly remove it from the context map and assume this will implicitly deleting the timer!
40 (WebCore::DOMTimer::fired):
41 - Add a RefPtr to keep the DOMTimer object alive until the fired method completes; to cancel a one-shot timer
42 just remove it from the context's map, rather than explicitly deleting it.
43 (WebCore::DOMTimer::~DOMTimer): Deleted.
44 (WebCore::DOMTimer::contextDestroyed): Deleted.
45 - no need! object lifetime management now handled by smart pointers.
46 * page/DOMTimer.h:
47 - added parent class RefCounted<DOMTimer>.
48