OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "core/inspector/TraceEventDispatcher.h" | |
33 | |
34 #include "wtf/CurrentTime.h" | |
35 #include "wtf/Functional.h" | |
36 #include "wtf/MainThread.h" | |
37 #include "wtf/text/StringHash.h" | |
38 | |
39 namespace blink { | |
40 | |
41 void TraceEventDispatcher::dispatchEventOnAnyThread(char phase, const unsigned c
har*, const char* name, unsigned long long id, | |
42 int numArgs, const char* const* argNames, const unsigned char* argTypes, con
st unsigned long long* argValues, | |
43 unsigned char flags, double timestamp) | |
44 { | |
45 TraceEventDispatcher* self = instance(); | |
46 { | |
47 MutexLocker locker(self->m_mutex); | |
48 if (self->m_listeners->find(std::make_pair(name, phase)) == self->m_list
eners->end()) | |
49 return; | |
50 } | |
51 self->enqueueEvent(TraceEvent(timestamp, phase, name, id, currentThread(), n
umArgs, argNames, argTypes, argValues)); | |
52 if (isMainThread()) | |
53 self->processBackgroundEvents(); | |
54 } | |
55 | |
56 void TraceEventDispatcher::enqueueEvent(const TraceEvent& event) | |
57 { | |
58 const float eventProcessingThresholdInSeconds = 0.1; | |
59 { | |
60 MutexLocker locker(m_mutex); | |
61 m_backgroundEvents.append(event); | |
62 if (m_processEventsTaskInFlight || event.timestamp() - m_lastEventProces
singTime <= eventProcessingThresholdInSeconds) | |
63 return; | |
64 } | |
65 m_processEventsTaskInFlight = true; | |
66 callOnMainThread(bind(&TraceEventDispatcher::processBackgroundEventsTask, th
is)); | |
67 } | |
68 | |
69 void TraceEventDispatcher::processBackgroundEventsTask() | |
70 { | |
71 m_processEventsTaskInFlight = false; | |
72 processBackgroundEvents(); | |
73 } | |
74 | |
75 void TraceEventDispatcher::processBackgroundEvents() | |
76 { | |
77 ASSERT(isMainThread()); | |
78 Vector<TraceEvent> events; | |
79 { | |
80 MutexLocker locker(m_mutex); | |
81 m_lastEventProcessingTime = WTF::monotonicallyIncreasingTime(); | |
82 if (m_backgroundEvents.isEmpty()) | |
83 return; | |
84 events.reserveCapacity(m_backgroundEvents.capacity()); | |
85 m_backgroundEvents.swap(events); | |
86 } | |
87 for (size_t eventIndex = 0, size = events.size(); eventIndex < size; ++event
Index) { | |
88 const TraceEvent& event = events[eventIndex]; | |
89 ListenersMap::iterator it = m_listeners->find(std::make_pair(event.name(
), event.phase())); | |
90 if (it == m_listeners->end()) | |
91 continue; | |
92 WillBeHeapVector<OwnPtrWillBeMember<TraceEventListener> >& listeners = *
it->value.get(); | |
93 for (size_t listenerIndex = 0; listenerIndex < listeners.size(); ++liste
nerIndex) | |
94 listeners[listenerIndex]->call(event); | |
95 } | |
96 } | |
97 | |
98 void TraceEventDispatcher::addListener(const char* name, char phase, PassOwnPtrW
illBeRawPtr<TraceEventListener> listener, InspectorClient* client) | |
99 { | |
100 static const char CategoryFilter[] = "-*," TRACE_DISABLED_BY_DEFAULT("devtoo
ls.timeline") "," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame"); | |
101 | |
102 ASSERT(isMainThread()); | |
103 MutexLocker locker(m_mutex); | |
104 if (m_listeners->isEmpty()) | |
105 client->setTraceEventCallback(CategoryFilter, dispatchEventOnAnyThread); | |
106 ListenersMap::iterator it = m_listeners->find(std::make_pair(name, phase)); | |
107 if (it == m_listeners->end()) | |
108 m_listeners->add(std::make_pair(name, phase), adoptPtrWillBeNoop(new Wil
lBeHeapVector<OwnPtrWillBeMember<TraceEventListener> >())).storedValue->value->a
ppend(listener); | |
109 else | |
110 it->value->append(listener); | |
111 } | |
112 | |
113 void TraceEventDispatcher::removeAllListeners(void* eventTarget, InspectorClient
* client) | |
114 { | |
115 ASSERT(isMainThread()); | |
116 processBackgroundEvents(); | |
117 { | |
118 MutexLocker locker(m_mutex); | |
119 | |
120 ListenersMap remainingListeners; | |
121 for (ListenersMap::iterator it = m_listeners->begin(); it != m_listeners
->end(); ++it) { | |
122 WillBeHeapVector<OwnPtrWillBeMember<TraceEventListener> >& listeners
= *it->value.get(); | |
123 for (size_t j = 0; j < listeners.size();) { | |
124 if (listeners[j]->target() == eventTarget) | |
125 listeners.remove(j); | |
126 else | |
127 ++j; | |
128 } | |
129 if (!listeners.isEmpty()) | |
130 remainingListeners.add(it->key, it->value.release()); | |
131 } | |
132 m_listeners->swap(remainingListeners); | |
133 } | |
134 if (m_listeners->isEmpty()) | |
135 client->resetTraceEventCallback(); | |
136 } | |
137 | |
138 size_t TraceEventDispatcher::TraceEvent::findParameter(const char* name) const | |
139 { | |
140 for (int i = 0; i < m_argumentCount; ++i) { | |
141 if (!strcmp(name, m_argumentNames[i])) | |
142 return i; | |
143 } | |
144 return kNotFound; | |
145 } | |
146 | |
147 const TraceEvent::TraceValueUnion& TraceEventDispatcher::TraceEvent::parameter(c
onst char* name, unsigned char expectedType) const | |
148 { | |
149 static blink::TraceEvent::TraceValueUnion missingValue; | |
150 size_t index = findParameter(name); | |
151 ASSERT(isMainThread()); | |
152 if (index == kNotFound || m_argumentTypes[index] != expectedType) { | |
153 ASSERT_NOT_REACHED(); | |
154 return missingValue; | |
155 } | |
156 return m_argumentValues[index]; | |
157 } | |
158 | |
159 } // namespace blink | |
160 | |
OLD | NEW |