Changeset 117501 in webkit
- Timestamp:
- May 17, 2012, 2:49:43 PM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
loader/icon/IconDatabase.cpp (modified) (13 diffs)
-
loader/icon/IconDatabase.h (modified) (6 diffs)
-
loader/icon/PageURLRecord.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r117497 r117501 1 2012-05-15 Andreas Kling <kling@webkit.org> 2 3 IconDatabase: Move icon retain/release off of the main thread. 4 <http://webkit.org/b/85799> 5 <rdar://problem/9507113> 6 7 Reviewed by Brady Eidson. 8 9 Batch up the retain/release operations and execute them as part of the sync thread loop. 10 The batch execution is guarded by a new mutex (m_urlsToRetainOrReleaseLock.) 11 This avoids blocking the main thread on m_urlAndIconLock for basic retain/release. 12 13 There is one exception; if there are pending retain/release operations in synchronousIconForPageURL, 14 it will acquire the lock and flush the operations. 15 16 There should be no behavior change, this is only meant to reduce lock contention. 17 18 * loader/icon/PageURLRecord.h: 19 (WebCore::PageURLRecord::retain): 20 (WebCore::PageURLRecord::release): 21 22 Added a 'count' argument to these so we can batch up the operations in IconDatabase. 23 24 * loader/icon/IconDatabase.h: 25 * loader/icon/IconDatabase.cpp: 26 (WebCore::IconDatabase::performScheduleOrDeferSyncTimer): 27 (WebCore::IconDatabase::performScheduleOrDeferSyncTimerOnMainThread): 28 (WebCore::IconDatabase::scheduleOrDeferSyncTimer): 29 30 Perform the the timer scheduling on the main thread as it can be done on a different 31 thread by way of retainIconForPageURL or releaseIconForPageURL. 32 33 (WebCore::IconDatabase::synchronousIconForPageURL): 34 (WebCore::IconDatabase::retainIconForPageURL): 35 (WebCore::IconDatabase::performRetainIconForPageURL): 36 (WebCore::IconDatabase::releaseIconForPageURL): 37 (WebCore::IconDatabase::performReleaseIconForPageURL): 38 (WebCore::IconDatabase::retainedPageURLCount): 39 (WebCore::IconDatabase::IconDatabase): 40 (WebCore::IconDatabase::performURLImport): 41 (WebCore::IconDatabase::syncThreadMainLoop): 42 (WebCore::IconDatabase::performPendingRetainAndReleaseOperations): 43 1 44 2012-05-17 Julien Chaffraix <jchaffraix@webkit.org> 2 45 -
trunk/Source/WebCore/loader/icon/IconDatabase.cpp
r116970 r117501 223 223 224 224 MutexLocker locker(m_urlAndIconLock); 225 226 if (m_retainOrReleaseIconRequested) 227 performPendingRetainAndReleaseOperations(); 225 228 226 229 String pageURLCopy; // Creates a null string for easy testing … … 390 393 } 391 394 392 393 void IconDatabase::retainIconForPageURL(const String& pageURLOriginal) 394 { 395 void IconDatabase::retainIconForPageURL(const String& pageURL) 396 { 395 397 ASSERT_NOT_SYNC_THREAD(); 396 397 // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first 398 399 if (!isEnabled() || !documentCanHaveIcon(pageURLOriginal)) 398 399 if (!isEnabled() || !documentCanHaveIcon(pageURL)) 400 400 return; 401 401 402 MutexLocker locker(m_urlAndIconLock); 403 402 MutexLocker locker(m_urlsToRetainOrReleaseLock); 403 m_urlsToRetain.add(pageURL); 404 scheduleOrDeferSyncTimer(); 405 } 406 407 void IconDatabase::performRetainIconForPageURL(const String& pageURLOriginal, int retainCount) 408 { 404 409 PageURLRecord* record = m_pageURLToRecordMap.get(pageURLOriginal); 405 410 … … 413 418 } 414 419 415 if (!record->retain( )) {420 if (!record->retain(retainCount)) { 416 421 if (pageURL.isNull()) 417 422 pageURL = pageURLOriginal.isolatedCopy(); … … 435 440 } 436 441 437 void IconDatabase::releaseIconForPageURL(const String& pageURL Original)442 void IconDatabase::releaseIconForPageURL(const String& pageURL) 438 443 { 439 444 ASSERT_NOT_SYNC_THREAD(); … … 441 446 // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first 442 447 443 if (!isEnabled() || !documentCanHaveIcon(pageURLOriginal)) 444 return; 445 446 MutexLocker locker(m_urlAndIconLock); 447 448 if (!isEnabled() || !documentCanHaveIcon(pageURL)) 449 return; 450 451 MutexLocker locker(m_urlsToRetainOrReleaseLock); 452 m_urlsToRelease.add(pageURL); 453 m_retainOrReleaseIconRequested = true; 454 scheduleOrDeferSyncTimer(); 455 } 456 457 void IconDatabase::performReleaseIconForPageURL(const String& pageURLOriginal, int releaseCount) 458 { 448 459 // Check if this pageURL is actually retained 449 460 if (!m_retainedPageURLs.contains(pageURLOriginal)) { … … 459 470 460 471 // If it still has a positive retain count, store the new count and bail 461 if (pageRecord->release( ))472 if (pageRecord->release(releaseCount)) 462 473 return; 463 474 … … 499 510 500 511 delete pageRecord; 501 502 if (isOpen())503 scheduleOrDeferSyncTimer();504 512 } 505 513 … … 737 745 { 738 746 MutexLocker locker(m_urlAndIconLock); 747 748 if (m_retainOrReleaseIconRequested) 749 performPendingRetainAndReleaseOperations(); 750 739 751 return m_retainedPageURLs.size(); 740 752 } … … 763 775 : m_syncTimer(this, &IconDatabase::syncTimerFired) 764 776 , m_syncThreadRunning(false) 777 , m_scheduleOrDeferSyncTimerRequested(false) 765 778 , m_isEnabled(false) 766 779 , m_privateBrowsingEnabled(false) … … 824 837 } 825 838 839 void IconDatabase::performScheduleOrDeferSyncTimer() 840 { 841 m_syncTimer.startOneShot(updateTimerDelay); 842 m_scheduleOrDeferSyncTimerRequested = false; 843 } 844 845 void IconDatabase::performScheduleOrDeferSyncTimerOnMainThread(void* context) 846 { 847 static_cast<IconDatabase*>(context)->performScheduleOrDeferSyncTimer(); 848 } 849 826 850 void IconDatabase::scheduleOrDeferSyncTimer() 827 851 { 828 852 ASSERT_NOT_SYNC_THREAD(); 829 853 830 if (!m_syncTimer.isActive()) { 831 // The following is balanced by the call to enableSuddenTermination in the 832 // syncTimerFired function. 833 disableSuddenTermination(); 834 } 835 836 m_syncTimer.startOneShot(updateTimerDelay); 854 if (m_scheduleOrDeferSyncTimerRequested) 855 return; 856 857 // The following is balanced by the call to enableSuddenTermination in the 858 // syncTimerFired function. 859 disableSuddenTermination(); 860 861 m_scheduleOrDeferSyncTimerRequested = true; 862 callOnMainThread(performScheduleOrDeferSyncTimerOnMainThread, this); 837 863 } 838 864 … … 1307 1333 { 1308 1334 MutexLocker locker(m_urlAndIconLock); 1309 1335 1336 if (m_retainOrReleaseIconRequested) 1337 performPendingRetainAndReleaseOperations(); 1338 1310 1339 for (unsigned i = 0; i < urls.size(); ++i) { 1311 1340 if (!m_retainedPageURLs.contains(urls[i])) { … … 1388 1417 if (m_threadTerminationRequested) 1389 1418 break; 1419 1420 if (m_retainOrReleaseIconRequested) { 1421 MutexLocker locker(m_urlAndIconLock); 1422 performPendingRetainAndReleaseOperations(); 1423 } 1390 1424 1391 1425 bool didAnyWork = true; … … 1470 1504 m_disabledSuddenTerminationForSyncThread = false; 1471 1505 } 1506 } 1507 1508 void IconDatabase::performPendingRetainAndReleaseOperations() 1509 { 1510 ASSERT(m_retainOrReleaseIconRequested); 1511 1512 // NOTE: The caller is assumed to hold m_urlAndIconLock. 1513 ASSERT(!m_urlAndIconLock.tryLock()); 1514 1515 MutexLocker vectorLocker(m_urlsToRetainOrReleaseLock); 1516 1517 for (HashCountedSet<String>::const_iterator it = m_urlsToRetain.begin(), end = m_urlsToRetain.end(); it != end; ++it) 1518 performRetainIconForPageURL(it->first, it->second); 1519 for (HashCountedSet<String>::const_iterator it = m_urlsToRelease.begin(), end = m_urlsToRelease.end(); it != end; ++it) 1520 performReleaseIconForPageURL(it->first, it->second); 1521 1522 m_urlsToRetain.clear(); 1523 m_urlsToRelease.clear(); 1524 m_retainOrReleaseIconRequested = false; 1472 1525 } 1473 1526 -
trunk/Source/WebCore/loader/icon/IconDatabase.h
r116970 r117501 30 30 #include "IconDatabaseBase.h" 31 31 #include "Timer.h" 32 #include <wtf/HashCountedSet.h> 32 33 #include <wtf/HashMap.h> 33 34 #include <wtf/HashSet.h> … … 136 137 RefPtr<IconRecord> m_defaultIconRecord; 137 138 139 static void performScheduleOrDeferSyncTimerOnMainThread(void*); 140 void performScheduleOrDeferSyncTimer(); 141 142 bool m_scheduleOrDeferSyncTimerRequested; 143 138 144 // *** Any Thread *** 139 145 public: … … 160 166 bool m_syncThreadHasWorkToDo; 161 167 bool m_disabledSuddenTerminationForSyncThread; 168 bool m_retainOrReleaseIconRequested; 162 169 163 170 Mutex m_urlAndIconLock; … … 177 184 HashSet<String> m_pageURLsInterestedInIcons; 178 185 HashSet<IconRecord*> m_iconsPendingReading; 186 187 Mutex m_urlsToRetainOrReleaseLock; 188 // Holding m_urlsToRetainOrReleaseLock is required when accessing any of the following data structures. 189 HashCountedSet<String> m_urlsToRetain; 190 HashCountedSet<String> m_urlsToRelease; 179 191 180 192 // *** Sync Thread Only *** … … 203 215 void deleteAllPreparedStatements(); 204 216 void* cleanupSyncThread(); 217 void performRetainIconForPageURL(const String&, int retainCount); 218 void performReleaseIconForPageURL(const String&, int releaseCount); 205 219 206 220 // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse) … … 221 235 void removeIconFromSQLDatabase(const String& iconURL); 222 236 void writeIconSnapshotToSQLDatabase(const IconSnapshot&); 223 237 238 void performPendingRetainAndReleaseOperations(); 239 224 240 // Methods to dispatch client callbacks on the main thread 225 241 void dispatchDidImportIconURLForPageURLOnMainThread(const String&); -
trunk/Source/WebCore/loader/icon/PageURLRecord.h
r83234 r117501 70 70 71 71 // Returns false if the page wasn't retained beforehand, true if the retain count was already 1 or higher 72 inline bool retain() { return m_retainCount++; } 72 bool retain(int count) 73 { 74 bool wasRetained = m_retainCount > 0; 75 m_retainCount += count; 76 return wasRetained; 77 } 73 78 74 79 // Returns true if the page is still retained after the call. False if the retain count just dropped to 0 75 inline bool release()80 bool release(int count) 76 81 { 77 ASSERT(m_retainCount > 0); 78 return --m_retainCount; 82 ASSERT(m_retainCount >= count); 83 m_retainCount -= count; 84 return m_retainCount > 0; 79 85 } 80 86
Note:
See TracChangeset
for help on using the changeset viewer.