OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 | 107 |
108 void LocalDOMWindow::WindowFrameObserver::contextDestroyed() | 108 void LocalDOMWindow::WindowFrameObserver::contextDestroyed() |
109 { | 109 { |
110 m_window->frameDestroyed(); | 110 m_window->frameDestroyed(); |
111 LocalFrameLifecycleObserver::contextDestroyed(); | 111 LocalFrameLifecycleObserver::contextDestroyed(); |
112 } | 112 } |
113 | 113 |
114 class PostMessageTimer final : public NoBaseWillBeGarbageCollectedFinalized<Post MessageTimer>, public SuspendableTimer { | 114 class PostMessageTimer final : public NoBaseWillBeGarbageCollectedFinalized<Post MessageTimer>, public SuspendableTimer { |
115 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PostMessageTimer); | 115 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PostMessageTimer); |
116 public: | 116 public: |
117 PostMessageTimer(LocalDOMWindow& window, PassRefPtrWillBeRawPtr<MessageEvent > event, PassRefPtrWillBeRawPtr<LocalDOMWindow> source, SecurityOrigin* targetOr igin, PassRefPtr<ScriptCallStack> stackTrace, UserGestureToken* userGestureToken ) | 117 PostMessageTimer(LocalDOMWindow& window, PassRefPtrWillBeRawPtr<MessageEvent > event, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace, U serGestureToken* userGestureToken) |
118 : SuspendableTimer(window.document()) | 118 : SuspendableTimer(window.document()) |
119 , m_event(event) | 119 , m_event(event) |
120 , m_window(&window) | 120 , m_window(&window) |
121 , m_targetOrigin(targetOrigin) | 121 , m_targetOrigin(targetOrigin) |
122 , m_stackTrace(stackTrace) | 122 , m_stackTrace(stackTrace) |
123 , m_userGestureToken(userGestureToken) | 123 , m_userGestureToken(userGestureToken) |
124 , m_preventDestruction(false) | 124 , m_disposalAllowed(true) |
125 { | 125 { |
126 m_asyncOperationId = InspectorInstrumentation::traceAsyncOperationStarti ng(executionContext(), "postMessage"); | 126 m_asyncOperationId = InspectorInstrumentation::traceAsyncOperationStarti ng(executionContext(), "postMessage"); |
127 } | 127 } |
128 | 128 |
129 PassRefPtrWillBeRawPtr<MessageEvent> event() const { return m_event.get(); } | 129 PassRefPtrWillBeRawPtr<MessageEvent> event() const { return m_event.get(); } |
130 SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } | 130 SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } |
131 ScriptCallStack* stackTrace() const { return m_stackTrace.get(); } | 131 ScriptCallStack* stackTrace() const { return m_stackTrace.get(); } |
132 UserGestureToken* userGestureToken() const { return m_userGestureToken.get() ; } | 132 UserGestureToken* userGestureToken() const { return m_userGestureToken.get() ; } |
133 void stop() override | 133 void stop() override |
134 { | 134 { |
135 SuspendableTimer::stop(); | 135 SuspendableTimer::stop(); |
136 | 136 |
137 if (!m_preventDestruction) { | 137 if (m_disposalAllowed) |
138 // Will destroy this object | 138 dispose(); |
139 m_window->removePostMessageTimer(this); | |
140 } | |
141 } | 139 } |
142 | 140 |
143 // Eager finalization is needed to promptly stop this timer object. | 141 // Eager finalization is needed to promptly stop this timer object. |
144 // (see DOMTimer comment for more.) | 142 // (see DOMTimer comment for more.) |
145 EAGERLY_FINALIZE(); | 143 EAGERLY_FINALIZE(); |
146 DEFINE_INLINE_VIRTUAL_TRACE() | 144 DEFINE_INLINE_VIRTUAL_TRACE() |
147 { | 145 { |
148 visitor->trace(m_event); | 146 visitor->trace(m_event); |
149 visitor->trace(m_window); | 147 visitor->trace(m_window); |
150 SuspendableTimer::trace(visitor); | 148 SuspendableTimer::trace(visitor); |
151 } | 149 } |
152 | 150 |
153 // TODO(alexclarke): Override timerTaskRunner() to pass in a document specif ic default task runner. | 151 // TODO(alexclarke): Override timerTaskRunner() to pass in a document specif ic default task runner. |
154 | 152 |
155 private: | 153 private: |
156 void fired() override | 154 void fired() override |
157 { | 155 { |
158 InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceA syncOperationCompletedCallbackStarting(executionContext(), m_asyncOperationId); | 156 InspectorInstrumentationCookie cookie = InspectorInstrumentation::traceA syncOperationCompletedCallbackStarting(executionContext(), m_asyncOperationId); |
159 // Prevent calls to stop triggered from the event handler to | 157 m_disposalAllowed = false; |
haraken
2016/02/17 13:52:37
How about moving this line into dispose()?
sof
2016/02/17 13:55:40
I don't see how that's possible given that we want
haraken
2016/02/17 13:57:19
Makes sense.
| |
160 // kill this object. | |
161 m_preventDestruction = true; | |
162 m_window->postMessageTimerFired(this); | 158 m_window->postMessageTimerFired(this); |
163 // Will destroy this object | 159 dispose(); |
160 InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); | |
161 } | |
162 | |
163 void dispose() | |
164 { | |
165 // Oilpan optimization: unregister as an observer right away. | |
166 clearContext(); | |
167 // Will destroy this object, now or after the next GC depending | |
168 // on whether Oilpan is disabled or not. | |
164 m_window->removePostMessageTimer(this); | 169 m_window->removePostMessageTimer(this); |
165 InspectorInstrumentation::traceAsyncCallbackCompleted(cookie); | |
166 } | 170 } |
167 | 171 |
168 RefPtrWillBeMember<MessageEvent> m_event; | 172 RefPtrWillBeMember<MessageEvent> m_event; |
169 RawPtrWillBeMember<LocalDOMWindow> m_window; | 173 RawPtrWillBeMember<LocalDOMWindow> m_window; |
170 RefPtr<SecurityOrigin> m_targetOrigin; | 174 RefPtr<SecurityOrigin> m_targetOrigin; |
171 RefPtr<ScriptCallStack> m_stackTrace; | 175 RefPtr<ScriptCallStack> m_stackTrace; |
172 RefPtr<UserGestureToken> m_userGestureToken; | 176 RefPtr<UserGestureToken> m_userGestureToken; |
173 int m_asyncOperationId; | 177 int m_asyncOperationId; |
174 bool m_preventDestruction; | 178 bool m_disposalAllowed; |
175 }; | 179 }; |
176 | 180 |
177 static void updateSuddenTerminationStatus(LocalDOMWindow* domWindow, bool addedL istener, FrameLoaderClient::SuddenTerminationDisablerType disablerType) | 181 static void updateSuddenTerminationStatus(LocalDOMWindow* domWindow, bool addedL istener, FrameLoaderClient::SuddenTerminationDisablerType disablerType) |
178 { | 182 { |
179 Platform::current()->suddenTerminationChanged(!addedListener); | 183 Platform::current()->suddenTerminationChanged(!addedListener); |
180 if (domWindow->frame() && domWindow->frame()->loader().client()) | 184 if (domWindow->frame() && domWindow->frame()->loader().client()) |
181 domWindow->frame()->loader().client()->suddenTerminationDisablerChanged( addedListener, disablerType); | 185 domWindow->frame()->loader().client()->suddenTerminationDisablerChanged( addedListener, disablerType); |
182 } | 186 } |
183 | 187 |
184 using DOMWindowSet = WillBePersistentHeapHashCountedSet<RawPtrWillBeWeakMember<L ocalDOMWindow>>; | 188 using DOMWindowSet = WillBePersistentHeapHashCountedSet<RawPtrWillBeWeakMember<L ocalDOMWindow>>; |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 return m_applicationCache.get(); | 672 return m_applicationCache.get(); |
669 } | 673 } |
670 | 674 |
671 Navigator* LocalDOMWindow::navigator() const | 675 Navigator* LocalDOMWindow::navigator() const |
672 { | 676 { |
673 if (!m_navigator) | 677 if (!m_navigator) |
674 m_navigator = Navigator::create(frame()); | 678 m_navigator = Navigator::create(frame()); |
675 return m_navigator.get(); | 679 return m_navigator.get(); |
676 } | 680 } |
677 | 681 |
678 void LocalDOMWindow::schedulePostMessage(PassRefPtrWillBeRawPtr<MessageEvent> ev ent, LocalDOMWindow* source, SecurityOrigin* target, PassRefPtr<ScriptCallStack> stackTrace) | 682 void LocalDOMWindow::schedulePostMessage(PassRefPtrWillBeRawPtr<MessageEvent> ev ent, SecurityOrigin* target, PassRefPtr<ScriptCallStack> stackTrace) |
679 { | 683 { |
684 // Allowing unbounded amounts of messages to build up for a suspended contex t | |
685 // is problematic; consider imposing a limit or other restriction if this | |
686 // surfaces often as a problem (see crbug.com/587012). | |
687 | |
680 // Schedule the message. | 688 // Schedule the message. |
681 OwnPtrWillBeRawPtr<PostMessageTimer> timer = adoptPtrWillBeNoop(new PostMess ageTimer(*this, event, source, target, stackTrace, UserGestureIndicator::current Token())); | 689 OwnPtrWillBeRawPtr<PostMessageTimer> timer = adoptPtrWillBeNoop(new PostMess ageTimer(*this, event, target, stackTrace, UserGestureIndicator::currentToken()) ); |
682 timer->startOneShot(0, BLINK_FROM_HERE); | 690 timer->startOneShot(0, BLINK_FROM_HERE); |
683 timer->suspendIfNeeded(); | 691 timer->suspendIfNeeded(); |
684 m_postMessageTimers.add(timer.release()); | 692 m_postMessageTimers.add(timer.release()); |
685 } | 693 } |
686 | 694 |
687 void LocalDOMWindow::postMessageTimerFired(PostMessageTimer* timer) | 695 void LocalDOMWindow::postMessageTimerFired(PostMessageTimer* timer) |
688 { | 696 { |
689 if (!isCurrentlyDisplayedInFrame()) { | 697 if (!isCurrentlyDisplayedInFrame()) |
690 return; | 698 return; |
691 } | |
692 | 699 |
693 RefPtrWillBeRawPtr<MessageEvent> event = timer->event(); | 700 RefPtrWillBeRawPtr<MessageEvent> event = timer->event(); |
694 | 701 |
695 UserGestureIndicator gestureIndicator(timer->userGestureToken()); | 702 UserGestureIndicator gestureIndicator(timer->userGestureToken()); |
696 | 703 |
697 event->entangleMessagePorts(document()); | 704 event->entangleMessagePorts(document()); |
698 dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->sta ckTrace()); | 705 dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->sta ckTrace()); |
699 } | 706 } |
700 | 707 |
701 void LocalDOMWindow::removePostMessageTimer(PostMessageTimer* timer) | 708 void LocalDOMWindow::removePostMessageTimer(PostMessageTimer* timer) |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1512 { | 1519 { |
1513 // If the LocalDOMWindow still has a frame reference, that frame must point | 1520 // If the LocalDOMWindow still has a frame reference, that frame must point |
1514 // back to this LocalDOMWindow: otherwise, it's easy to get into a situation | 1521 // back to this LocalDOMWindow: otherwise, it's easy to get into a situation |
1515 // where script execution leaks between different LocalDOMWindows. | 1522 // where script execution leaks between different LocalDOMWindows. |
1516 if (m_frameObserver->frame()) | 1523 if (m_frameObserver->frame()) |
1517 ASSERT_WITH_SECURITY_IMPLICATION(m_frameObserver->frame()->domWindow() = = this); | 1524 ASSERT_WITH_SECURITY_IMPLICATION(m_frameObserver->frame()->domWindow() = = this); |
1518 return m_frameObserver->frame(); | 1525 return m_frameObserver->frame(); |
1519 } | 1526 } |
1520 | 1527 |
1521 } // namespace blink | 1528 } // namespace blink |
OLD | NEW |