Changeset 128289 in webkit
- Timestamp:
- Sep 12, 2012 3:20:00 AM (12 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r128280 r128289 1 2012-09-12 Byungwoo Lee <bw80.lee@samsung.com> 2 3 [EFL][WK2] WorkQueue::dispatchAfterDelay() doesn't work properly. 4 https://bugs.webkit.org/show_bug.cgi?id=91179 5 6 Reviewed by Gyuyoung Kim. 7 8 When UI Process is crashed and WebProcess's ecore main loop is very 9 busy or lockup also, watchdocCallback() function in the 10 ChildProcess.cpp doesn't triggered. And this is because of that 11 WorkQueue::dispatchAfterDelay() function uses ecore timer for getting 12 timer event. 13 14 For removing the dependency between the dispatchAfterDelay() and ecore 15 main loop, new timer event mechanism is added to WorkQueue main loop. 16 17 * Platform/WorkQueue.h: 18 (TimerWorkItem): 19 (WorkQueue::TimerWorkItem::dispatch): 20 (WorkQueue::TimerWorkItem::expireTime): 21 (WorkQueue::TimerWorkItem::expired): 22 (WorkQueue): 23 * Platform/efl/WorkQueueEfl.cpp: 24 (WorkQueue::TimerWorkItem::create): 25 (WorkQueue::TimerWorkItem::TimerWorkItem): 26 (WorkQueue::performFileDescriptorWork): 27 (WorkQueue::getCurrentTime): 28 (WorkQueue::getNextTimeOut): 29 (WorkQueue::performTimerWork): 30 (WorkQueue::workQueueThread): 31 (WorkQueue::dispatchAfterDelay): 32 1 33 2012-09-12 Christophe Dumez <christophe.dumez@intel.com> 2 34 -
trunk/Source/WebKit2/Platform/WorkQueue.h
r127983 r128289 188 188 typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator; 189 189 #elif PLATFORM(EFL) 190 class TimerWorkItem { 191 public: 192 static PassOwnPtr<TimerWorkItem> create(Function<void()>, double expireTime); 193 void dispatch() { m_function(); } 194 double expireTime() const { return m_expireTime; } 195 bool expired(double currentTime) const { return currentTime >= m_expireTime; } 196 197 protected: 198 TimerWorkItem(Function<void()>, double expireTime); 199 200 private: 201 Function<void()> m_function; 202 double m_expireTime; 203 }; 204 190 205 fd_set m_fileDescriptorSet; 191 206 int m_maxFileDescriptor; … … 200 215 Function<void()> m_socketEventHandler; 201 216 202 HashMap<int, OwnPtr<Ecore_Timer> > m_timers; 217 Vector<OwnPtr<TimerWorkItem> > m_timerWorkItems; 218 Mutex m_timerWorkItemsLock; 203 219 204 220 void sendMessageToThread(const char*); … … 206 222 void performWork(); 207 223 void performFileDescriptorWork(); 208 static bool timerFired(void*); 224 static double getCurrentTime(); 225 struct timeval* getNextTimeOut(); 226 void performTimerWork(); 227 void insertTimerWorkItem(PassOwnPtr<TimerWorkItem>); 209 228 #endif 210 229 }; -
trunk/Source/WebKit2/Platform/efl/WorkQueueEfl.cpp
r122136 r128289 21 21 #include "WorkQueue.h" 22 22 23 #include <sys/timerfd.h> 23 24 #include <wtf/Assertions.h> 24 25 class TimerWorkItem { 26 public: 27 TimerWorkItem(int timerID, const Function<void()>& function, WorkQueue* queue) 28 : m_function(function) 29 , m_queue(queue) 30 , m_timerID(timerID) 31 { 32 } 33 ~TimerWorkItem() { } 34 35 Function<void()> function() const { return m_function; } 36 WorkQueue* queue() const { return m_queue; } 37 38 int timerID() const { return m_timerID; } 39 40 private: 41 Function<void()> m_function; 42 WorkQueue* m_queue; 43 int m_timerID; 44 }; 25 #include <wtf/CurrentTime.h> 45 26 46 27 static const int invalidSocketDescriptor = -1; … … 48 29 static const char finishThreadMessage[] = "F"; 49 30 static const char wakupThreadMessage[] = "W"; 31 32 PassOwnPtr<WorkQueue::TimerWorkItem> WorkQueue::TimerWorkItem::create(Function<void()> function, double expireTime) 33 { 34 if (expireTime < 0) 35 return nullptr; 36 37 return adoptPtr(new TimerWorkItem(function, expireTime)); 38 } 39 40 WorkQueue::TimerWorkItem::TimerWorkItem(Function<void()> function, double expireTime) 41 : m_function(function) 42 , m_expireTime(expireTime) 43 { 44 } 50 45 51 46 void WorkQueue::platformInitialize(const char* name) … … 92 87 fd_set readFileDescriptorSet = m_fileDescriptorSet; 93 88 94 if (select(m_maxFileDescriptor + 1, &readFileDescriptorSet, 0, 0, 0) >= 0) {89 if (select(m_maxFileDescriptor + 1, &readFileDescriptorSet, 0, 0, getNextTimeOut()) >= 0) { 95 90 if (FD_ISSET(m_readFromPipeDescriptor, &readFileDescriptorSet)) { 96 91 char readBuf[threadMessageSize]; … … 106 101 } 107 102 103 struct timeval* WorkQueue::getNextTimeOut() 104 { 105 MutexLocker locker(m_timerWorkItemsLock); 106 if (m_timerWorkItems.isEmpty()) 107 return 0; 108 109 static struct timeval timeValue; 110 timeValue.tv_sec = 0; 111 timeValue.tv_usec = 0; 112 double timeOut = m_timerWorkItems[0]->expireTime() - currentTime(); 113 if (timeOut > 0) { 114 timeValue.tv_sec = static_cast<long>(timeOut); 115 timeValue.tv_usec = static_cast<long>((timeOut - timeValue.tv_sec) * 1000000); 116 } 117 118 return &timeValue; 119 } 120 121 void WorkQueue::insertTimerWorkItem(PassOwnPtr<TimerWorkItem> item) 122 { 123 if (!item) 124 return; 125 126 size_t position = 0; 127 128 // m_timerWorkItems should be ordered by expire time. 129 for (; position < m_timerWorkItems.size(); ++position) 130 if (item->expireTime() < m_timerWorkItems[position]->expireTime()) 131 break; 132 133 m_timerWorkItems.insert(position, item); 134 } 135 136 void WorkQueue::performTimerWork() 137 { 138 // Protects m_timerWorkItems. 139 m_timerWorkItemsLock.lock(); 140 141 if (m_timerWorkItems.isEmpty()) { 142 m_timerWorkItemsLock.unlock(); 143 return; 144 } 145 146 double current = currentTime(); 147 Vector<OwnPtr<TimerWorkItem> > timerWorkItems; 148 149 // Copies all the timer work items in m_timerWorkItems to local vector. 150 m_timerWorkItems.swap(timerWorkItems); 151 152 for (size_t i = 0; i < timerWorkItems.size(); ++i) { 153 if (!timerWorkItems[i]->expired(current)) { 154 // If a timer work item does not expired, keep it to the m_timerWorkItems. 155 // m_timerWorkItems should be ordered by expire time. 156 insertTimerWorkItem(timerWorkItems[i].release()); 157 continue; 158 } 159 160 // If a timer work item expired, dispatch the function of the work item. 161 // Before dispatching, m_timerWorkItemsLock should unlock for preventing deadlock, 162 // because it can be accessed inside the function of the timer work item dispatched. 163 m_timerWorkItemsLock.unlock(); 164 timerWorkItems[i]->dispatch(); 165 m_timerWorkItemsLock.lock(); 166 } 167 168 m_timerWorkItemsLock.unlock(); 169 } 170 108 171 void WorkQueue::sendMessageToThread(const char* message) 109 172 { … … 116 179 while (workQueue->m_threadLoop) { 117 180 workQueue->performWork(); 181 workQueue->performTimerWork(); 118 182 workQueue->performFileDescriptorWork(); 119 183 } … … 154 218 } 155 219 156 bool WorkQueue::timerFired(void* data)157 {158 TimerWorkItem* item = static_cast<TimerWorkItem*>(data);159 if (item && item->queue()->m_isValid) {160 item->queue()->dispatch(item->function());161 item->queue()->m_timers.take(item->timerID());162 delete item;163 }164 165 return ECORE_CALLBACK_CANCEL;166 }167 168 220 void WorkQueue::dispatchAfterDelay(const Function<void()>& function, double delay) 169 221 { 170 static int timerId = 1; 171 m_timers.set(timerId, adoptPtr(ecore_timer_add(delay, reinterpret_cast<Ecore_Task_Cb>(timerFired), new TimerWorkItem(timerId, function, this)))); 172 timerId++; 173 } 222 if (delay < 0) 223 return; 224 225 MutexLocker locker(m_timerWorkItemsLock); 226 OwnPtr<TimerWorkItem> timerWorkItem = TimerWorkItem::create(function, currentTime() + delay); 227 if (!timerWorkItem) 228 return; 229 230 insertTimerWorkItem(timerWorkItem.release()); 231 sendMessageToThread(wakupThreadMessage); 232 }
Note: See TracChangeset
for help on using the changeset viewer.