| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) | 3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) |
| 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 ASSERT(!isOpen()); | 174 ASSERT(!isOpen()); |
| 175 } | 175 } |
| 176 | 176 |
| 177 void IconDatabase::removeAllIcons() | 177 void IconDatabase::removeAllIcons() |
| 178 { | 178 { |
| 179 ASSERT_NOT_SYNC_THREAD(); | 179 ASSERT_NOT_SYNC_THREAD(); |
| 180 | 180 |
| 181 if (!isOpen()) | 181 if (!isOpen()) |
| 182 return; | 182 return; |
| 183 | 183 |
| 184 LOG(IconDatabase, "Requesting background thread to remove all icons"); | 184 LOG_INFO(IconDatabase, "Requesting background thread to remove all icons"); |
| 185 | 185 |
| 186 // Clear the in-memory record of every IconRecord, anything waiting to be re
ad from disk, and anything waiting to be written to disk | 186 // Clear the in-memory record of every IconRecord, anything waiting to be re
ad from disk, and anything waiting to be written to disk |
| 187 { | 187 { |
| 188 MutexLocker locker(m_urlAndIconLock); | 188 MutexLocker locker(m_urlAndIconLock); |
| 189 | 189 |
| 190 // Clear the IconRecords for every page URL - RefCounting will cause the
IconRecords themselves to be deleted | 190 // Clear the IconRecords for every page URL - RefCounting will cause the
IconRecords themselves to be deleted |
| 191 // We don't delete the actual PageRecords because we have the "retain ic
on for url" count to keep track of | 191 // We don't delete the actual PageRecords because we have the "retain ic
on for url" count to keep track of |
| 192 HashMap<String, PageURLRecord*>::iterator iter = m_pageURLToRecordMap.be
gin(); | 192 HashMap<String, PageURLRecord*>::iterator iter = m_pageURLToRecordMap.be
gin(); |
| 193 HashMap<String, PageURLRecord*>::iterator end = m_pageURLToRecordMap.end
(); | 193 HashMap<String, PageURLRecord*>::iterator end = m_pageURLToRecordMap.end
(); |
| 194 for (; iter != end; ++iter) | 194 for (; iter != end; ++iter) |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 446 |
| 447 // If we read the iconURLs yet, we want to avoid any pageURL->iconURL lo
okups and the pageURLsPendingDeletion is moot, | 447 // If we read the iconURLs yet, we want to avoid any pageURL->iconURL lo
okups and the pageURLsPendingDeletion is moot, |
| 448 // so we bail here and skip those steps | 448 // so we bail here and skip those steps |
| 449 if (!m_iconURLImportComplete) | 449 if (!m_iconURLImportComplete) |
| 450 return; | 450 return; |
| 451 | 451 |
| 452 MutexLocker locker(m_pendingSyncLock); | 452 MutexLocker locker(m_pendingSyncLock); |
| 453 // If this pageURL waiting to be sync'ed, update the sync record | 453 // If this pageURL waiting to be sync'ed, update the sync record |
| 454 // This saves us in the case where a page was ready to be deleted from t
he database but was just retained - so theres no need to delete it! | 454 // This saves us in the case where a page was ready to be deleted from t
he database but was just retained - so theres no need to delete it! |
| 455 if (!m_privateBrowsingEnabled && m_pageURLsPendingSync.contains(pageURL)
) { | 455 if (!m_privateBrowsingEnabled && m_pageURLsPendingSync.contains(pageURL)
) { |
| 456 LOG(IconDatabase, "Bringing %s back from the brink", pageURL.ascii()
.data()); | 456 LOG_INFO(IconDatabase, "Bringing %s back from the brink", pageURL.as
cii().data()); |
| 457 m_pageURLsPendingSync.set(pageURL, record->snapshot()); | 457 m_pageURLsPendingSync.set(pageURL, record->snapshot()); |
| 458 } | 458 } |
| 459 } | 459 } |
| 460 } | 460 } |
| 461 | 461 |
| 462 void IconDatabase::releaseIconForPageURL(const String& pageURL) | 462 void IconDatabase::releaseIconForPageURL(const String& pageURL) |
| 463 { | 463 { |
| 464 ASSERT_NOT_SYNC_THREAD(); | 464 ASSERT_NOT_SYNC_THREAD(); |
| 465 | 465 |
| 466 // Cannot do anything with pageURLOriginal that would end up storing it with
out deep copying first | 466 // Cannot do anything with pageURLOriginal that would end up storing it with
out deep copying first |
| (...skipping 13 matching lines...) Expand all Loading... |
| 480 { | 480 { |
| 481 // Check if this pageURL is actually retained | 481 // Check if this pageURL is actually retained |
| 482 if (!m_retainedPageURLs.contains(pageURLOriginal)) { | 482 if (!m_retainedPageURLs.contains(pageURLOriginal)) { |
| 483 LOG_ERROR("Attempting to release icon for URL %s which is not retained",
urlForLogging(pageURLOriginal).ascii().data()); | 483 LOG_ERROR("Attempting to release icon for URL %s which is not retained",
urlForLogging(pageURLOriginal).ascii().data()); |
| 484 return; | 484 return; |
| 485 } | 485 } |
| 486 | 486 |
| 487 // Get its retain count - if it's retained, we'd better have a PageURLRecord
for it | 487 // Get its retain count - if it's retained, we'd better have a PageURLRecord
for it |
| 488 PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); | 488 PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); |
| 489 ASSERT(pageRecord); | 489 ASSERT(pageRecord); |
| 490 LOG(IconDatabase, "Releasing pageURL %s to a retain count of %i", urlForLogg
ing(pageURLOriginal).ascii().data(), pageRecord->retainCount() - 1); | 490 LOG_INFO(IconDatabase, "Releasing pageURL %s to a retain count of %i", urlFo
rLogging(pageURLOriginal).ascii().data(), pageRecord->retainCount() - 1); |
| 491 ASSERT(pageRecord->retainCount() > 0); | 491 ASSERT(pageRecord->retainCount() > 0); |
| 492 | 492 |
| 493 // If it still has a positive retain count, store the new count and bail | 493 // If it still has a positive retain count, store the new count and bail |
| 494 if (pageRecord->release(releaseCount)) | 494 if (pageRecord->release(releaseCount)) |
| 495 return; | 495 return; |
| 496 | 496 |
| 497 // This pageRecord has now been fully released. Do the appropriate cleanup | 497 // This pageRecord has now been fully released. Do the appropriate cleanup |
| 498 LOG(IconDatabase, "No more retainers for PageURL %s", urlForLogging(pageURLO
riginal).ascii().data()); | 498 LOG_INFO(IconDatabase, "No more retainers for PageURL %s", urlForLogging(pag
eURLOriginal).ascii().data()); |
| 499 m_pageURLToRecordMap.remove(pageURLOriginal); | 499 m_pageURLToRecordMap.remove(pageURLOriginal); |
| 500 m_retainedPageURLs.remove(pageURLOriginal); | 500 m_retainedPageURLs.remove(pageURLOriginal); |
| 501 | 501 |
| 502 // Grab the iconRecord for later use (and do a sanity check on it for kicks) | 502 // Grab the iconRecord for later use (and do a sanity check on it for kicks) |
| 503 IconRecord* iconRecord = pageRecord->iconRecord(); | 503 IconRecord* iconRecord = pageRecord->iconRecord(); |
| 504 | 504 |
| 505 ASSERT(!iconRecord || (iconRecord && m_iconURLToRecordMap.get(iconRecord->ic
onURL()) == iconRecord)); | 505 ASSERT(!iconRecord || (iconRecord && m_iconURLToRecordMap.get(iconRecord->ic
onURL()) == iconRecord)); |
| 506 | 506 |
| 507 { | 507 { |
| 508 MutexLocker locker(m_pendingReadingLock); | 508 MutexLocker locker(m_pendingReadingLock); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 pageURLs.appendRange(icon->retainingPageURLs().begin(), icon->retainingP
ageURLs().end()); | 567 pageURLs.appendRange(icon->retainingPageURLs().begin(), icon->retainingP
ageURLs().end()); |
| 568 | 568 |
| 569 // Mark the IconRecord as requiring an update to the database only if pr
ivate browsing is disabled | 569 // Mark the IconRecord as requiring an update to the database only if pr
ivate browsing is disabled |
| 570 if (!m_privateBrowsingEnabled) { | 570 if (!m_privateBrowsingEnabled) { |
| 571 MutexLocker locker(m_pendingSyncLock); | 571 MutexLocker locker(m_pendingSyncLock); |
| 572 m_iconsPendingSync.set(iconURL, icon->snapshot()); | 572 m_iconsPendingSync.set(iconURL, icon->snapshot()); |
| 573 } | 573 } |
| 574 | 574 |
| 575 if (icon->hasOneRef()) { | 575 if (icon->hasOneRef()) { |
| 576 ASSERT(icon->retainingPageURLs().isEmpty()); | 576 ASSERT(icon->retainingPageURLs().isEmpty()); |
| 577 LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - r
emoving mapping for it", urlForLogging(icon->iconURL()).ascii().data()); | 577 LOG_INFO(IconDatabase, "Icon for icon url %s is about to be destroye
d - removing mapping for it", urlForLogging(icon->iconURL()).ascii().data()); |
| 578 m_iconURLToRecordMap.remove(icon->iconURL()); | 578 m_iconURLToRecordMap.remove(icon->iconURL()); |
| 579 } | 579 } |
| 580 } | 580 } |
| 581 | 581 |
| 582 // Send notification out regarding all PageURLs that retain this icon | 582 // Send notification out regarding all PageURLs that retain this icon |
| 583 // But not if we're on the sync thread because that implies this mapping | 583 // But not if we're on the sync thread because that implies this mapping |
| 584 // comes from the initial import which we don't want notifications for | 584 // comes from the initial import which we don't want notifications for |
| 585 if (!IS_ICON_SYNC_THREAD()) { | 585 if (!IS_ICON_SYNC_THREAD()) { |
| 586 // Start the timer to commit this change - or further delay the timer if
it was already started | 586 // Start the timer to commit this change - or further delay the timer if
it was already started |
| 587 scheduleOrDeferSyncTimer(); | 587 scheduleOrDeferSyncTimer(); |
| 588 | 588 |
| 589 // Informal testing shows that draining the autorelease pool every 25 it
erations is about as low as we can go | 589 // Informal testing shows that draining the autorelease pool every 25 it
erations is about as low as we can go |
| 590 // before performance starts to drop off, but we don't want to increase
this number because then accumulated memory usage will go up | 590 // before performance starts to drop off, but we don't want to increase
this number because then accumulated memory usage will go up |
| 591 AutodrainedPool pool(25); | 591 AutodrainedPool pool(25); |
| 592 | 592 |
| 593 for (unsigned i = 0; i < pageURLs.size(); ++i) { | 593 for (unsigned i = 0; i < pageURLs.size(); ++i) { |
| 594 LOG(IconDatabase, "Dispatching notification that retaining pageURL %
s has a new icon", urlForLogging(pageURLs[i]).ascii().data()); | 594 LOG_INFO(IconDatabase, "Dispatching notification that retaining page
URL %s has a new icon", urlForLogging(pageURLs[i]).ascii().data()); |
| 595 m_client->didChangeIconForPageURL(pageURLs[i]); | 595 m_client->didChangeIconForPageURL(pageURLs[i]); |
| 596 | 596 |
| 597 pool.cycle(); | 597 pool.cycle(); |
| 598 } | 598 } |
| 599 } | 599 } |
| 600 } | 600 } |
| 601 | 601 |
| 602 void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
ing& pageURLOriginal) | 602 void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
ing& pageURLOriginal) |
| 603 { | 603 { |
| 604 ASSERT_NOT_SYNC_THREAD(); | 604 ASSERT_NOT_SYNC_THREAD(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 632 | 632 |
| 633 RefPtr<IconRecord> iconRecord = pageRecord->iconRecord(); | 633 RefPtr<IconRecord> iconRecord = pageRecord->iconRecord(); |
| 634 | 634 |
| 635 // Otherwise, set the new icon record for this page | 635 // Otherwise, set the new icon record for this page |
| 636 pageRecord->setIconRecord(getOrCreateIconRecord(iconURL)); | 636 pageRecord->setIconRecord(getOrCreateIconRecord(iconURL)); |
| 637 | 637 |
| 638 // If the current icon has only a single ref left, it is about to get wi
ped out. | 638 // If the current icon has only a single ref left, it is about to get wi
ped out. |
| 639 // Remove it from the in-memory records and don't bother reading it in f
rom disk anymore | 639 // Remove it from the in-memory records and don't bother reading it in f
rom disk anymore |
| 640 if (iconRecord && iconRecord->hasOneRef()) { | 640 if (iconRecord && iconRecord->hasOneRef()) { |
| 641 ASSERT(iconRecord->retainingPageURLs().size() == 0); | 641 ASSERT(iconRecord->retainingPageURLs().size() == 0); |
| 642 LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - r
emoving mapping for it", urlForLogging(iconRecord->iconURL()).ascii().data()); | 642 LOG_INFO(IconDatabase, "Icon for icon url %s is about to be destroye
d - removing mapping for it", urlForLogging(iconRecord->iconURL()).ascii().data(
)); |
| 643 m_iconURLToRecordMap.remove(iconRecord->iconURL()); | 643 m_iconURLToRecordMap.remove(iconRecord->iconURL()); |
| 644 MutexLocker locker(m_pendingReadingLock); | 644 MutexLocker locker(m_pendingReadingLock); |
| 645 m_iconsPendingReading.remove(iconRecord.get()); | 645 m_iconsPendingReading.remove(iconRecord.get()); |
| 646 } | 646 } |
| 647 | 647 |
| 648 // And mark this mapping to be added to the database | 648 // And mark this mapping to be added to the database |
| 649 if (!m_privateBrowsingEnabled) { | 649 if (!m_privateBrowsingEnabled) { |
| 650 MutexLocker locker(m_pendingSyncLock); | 650 MutexLocker locker(m_pendingSyncLock); |
| 651 m_pageURLsPendingSync.set(pageURL, pageRecord->snapshot()); | 651 m_pageURLsPendingSync.set(pageURL, pageRecord->snapshot()); |
| 652 | 652 |
| 653 // If the icon is on its last ref, mark it for deletion | 653 // If the icon is on its last ref, mark it for deletion |
| 654 if (iconRecord && iconRecord->hasOneRef()) | 654 if (iconRecord && iconRecord->hasOneRef()) |
| 655 m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapsh
ot(true)); | 655 m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapsh
ot(true)); |
| 656 } | 656 } |
| 657 } | 657 } |
| 658 | 658 |
| 659 // Since this mapping is new, send the notification out - but not if we're o
n the sync thread because that implies this mapping | 659 // Since this mapping is new, send the notification out - but not if we're o
n the sync thread because that implies this mapping |
| 660 // comes from the initial import which we don't want notifications for | 660 // comes from the initial import which we don't want notifications for |
| 661 if (!IS_ICON_SYNC_THREAD()) { | 661 if (!IS_ICON_SYNC_THREAD()) { |
| 662 // Start the timer to commit this change - or further delay the timer if
it was already started | 662 // Start the timer to commit this change - or further delay the timer if
it was already started |
| 663 scheduleOrDeferSyncTimer(); | 663 scheduleOrDeferSyncTimer(); |
| 664 | 664 |
| 665 LOG(IconDatabase, "Dispatching notification that we changed an icon mapp
ing for url %s", urlForLogging(pageURL).ascii().data()); | 665 LOG_INFO(IconDatabase, "Dispatching notification that we changed an icon
mapping for url %s", urlForLogging(pageURL).ascii().data()); |
| 666 AutodrainedPool pool; | 666 AutodrainedPool pool; |
| 667 m_client->didChangeIconForPageURL(pageURL); | 667 m_client->didChangeIconForPageURL(pageURL); |
| 668 } | 668 } |
| 669 } | 669 } |
| 670 | 670 |
| 671 IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& i
conURL, DocumentLoader* notificationDocumentLoader) | 671 IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& i
conURL, DocumentLoader* notificationDocumentLoader) |
| 672 { | 672 { |
| 673 ASSERT_NOT_SYNC_THREAD(); | 673 ASSERT_NOT_SYNC_THREAD(); |
| 674 | 674 |
| 675 if (!isOpen() || iconURL.isEmpty()) | 675 if (!isOpen() || iconURL.isEmpty()) |
| 676 return IconLoadNo; | 676 return IconLoadNo; |
| 677 | 677 |
| 678 // If we have a IconRecord, it should also have its timeStamp marked because
there is only two times when we create the IconRecord: | 678 // If we have a IconRecord, it should also have its timeStamp marked because
there is only two times when we create the IconRecord: |
| 679 // 1 - When we read the icon urls from disk, getting the timeStamp at the sa
me time | 679 // 1 - When we read the icon urls from disk, getting the timeStamp at the sa
me time |
| 680 // 2 - When we get a new icon from the loader, in which case the timestamp i
s set at that time | 680 // 2 - When we get a new icon from the loader, in which case the timestamp i
s set at that time |
| 681 { | 681 { |
| 682 MutexLocker locker(m_urlAndIconLock); | 682 MutexLocker locker(m_urlAndIconLock); |
| 683 if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) { | 683 if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) { |
| 684 LOG(IconDatabase, "Found expiration time on a present icon based on
existing IconRecord"); | 684 LOG_INFO(IconDatabase, "Found expiration time on a present icon base
d on existing IconRecord"); |
| 685 return static_cast<int>(currentTime()) - static_cast<int>(icon->getT
imestamp()) > iconExpirationTime ? IconLoadYes : IconLoadNo; | 685 return static_cast<int>(currentTime()) - static_cast<int>(icon->getT
imestamp()) > iconExpirationTime ? IconLoadYes : IconLoadNo; |
| 686 } | 686 } |
| 687 } | 687 } |
| 688 | 688 |
| 689 // If we don't have a record for it, but we *have* imported all iconURLs fro
m disk, then we should load it now | 689 // If we don't have a record for it, but we *have* imported all iconURLs fro
m disk, then we should load it now |
| 690 MutexLocker readingLocker(m_pendingReadingLock); | 690 MutexLocker readingLocker(m_pendingReadingLock); |
| 691 if (m_iconURLImportComplete) | 691 if (m_iconURLImportComplete) |
| 692 return IconLoadYes; | 692 return IconLoadYes; |
| 693 | 693 |
| 694 // Otherwise - since we refuse to perform I/O on the main thread to find out
for sure - we return the answer that says | 694 // Otherwise - since we refuse to perform I/O on the main thread to find out
for sure - we return the answer that says |
| 695 // "You might be asked to load this later, so flag that" | 695 // "You might be asked to load this later, so flag that" |
| 696 LOG(IconDatabase, "Don't know if we should load %s or not - adding %p to the
set of document loaders waiting on a decision", iconURL.ascii().data(), notific
ationDocumentLoader); | 696 LOG_INFO(IconDatabase, "Don't know if we should load %s or not - adding %p t
o the set of document loaders waiting on a decision", iconURL.ascii().data(), no
tificationDocumentLoader); |
| 697 if (notificationDocumentLoader) | 697 if (notificationDocumentLoader) |
| 698 m_loadersPendingDecision.add(notificationDocumentLoader); | 698 m_loadersPendingDecision.add(notificationDocumentLoader); |
| 699 | 699 |
| 700 return IconLoadUnknown; | 700 return IconLoadUnknown; |
| 701 } | 701 } |
| 702 | 702 |
| 703 bool IconDatabase::synchronousIconDataKnownForIconURL(const String& iconURL) | 703 bool IconDatabase::synchronousIconDataKnownForIconURL(const String& iconURL) |
| 704 { | 704 { |
| 705 ASSERT_NOT_SYNC_THREAD(); | 705 ASSERT_NOT_SYNC_THREAD(); |
| 706 | 706 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 734 | 734 |
| 735 bool IconDatabase::isPrivateBrowsingEnabled() const | 735 bool IconDatabase::isPrivateBrowsingEnabled() const |
| 736 { | 736 { |
| 737 return m_privateBrowsingEnabled; | 737 return m_privateBrowsingEnabled; |
| 738 } | 738 } |
| 739 | 739 |
| 740 void IconDatabase::delayDatabaseCleanup() | 740 void IconDatabase::delayDatabaseCleanup() |
| 741 { | 741 { |
| 742 ++databaseCleanupCounter; | 742 ++databaseCleanupCounter; |
| 743 if (databaseCleanupCounter == 1) | 743 if (databaseCleanupCounter == 1) |
| 744 LOG(IconDatabase, "Database cleanup is now DISABLED"); | 744 LOG_INFO(IconDatabase, "Database cleanup is now DISABLED"); |
| 745 } | 745 } |
| 746 | 746 |
| 747 void IconDatabase::allowDatabaseCleanup() | 747 void IconDatabase::allowDatabaseCleanup() |
| 748 { | 748 { |
| 749 if (--databaseCleanupCounter < 0) | 749 if (--databaseCleanupCounter < 0) |
| 750 databaseCleanupCounter = 0; | 750 databaseCleanupCounter = 0; |
| 751 if (databaseCleanupCounter == 0) | 751 if (databaseCleanupCounter == 0) |
| 752 LOG(IconDatabase, "Database cleanup is now ENABLED"); | 752 LOG_INFO(IconDatabase, "Database cleanup is now ENABLED"); |
| 753 } | 753 } |
| 754 | 754 |
| 755 void IconDatabase::checkIntegrityBeforeOpening() | 755 void IconDatabase::checkIntegrityBeforeOpening() |
| 756 { | 756 { |
| 757 checkIntegrityOnOpen = true; | 757 checkIntegrityOnOpen = true; |
| 758 } | 758 } |
| 759 | 759 |
| 760 size_t IconDatabase::pageURLMappingCount() | 760 size_t IconDatabase::pageURLMappingCount() |
| 761 { | 761 { |
| 762 MutexLocker locker(m_urlAndIconLock); | 762 MutexLocker locker(m_urlAndIconLock); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 , m_privateBrowsingEnabled(false) | 798 , m_privateBrowsingEnabled(false) |
| 799 , m_threadTerminationRequested(false) | 799 , m_threadTerminationRequested(false) |
| 800 , m_removeIconsRequested(false) | 800 , m_removeIconsRequested(false) |
| 801 , m_iconURLImportComplete(false) | 801 , m_iconURLImportComplete(false) |
| 802 , m_syncThreadHasWorkToDo(false) | 802 , m_syncThreadHasWorkToDo(false) |
| 803 , m_disabledSuddenTerminationForSyncThread(false) | 803 , m_disabledSuddenTerminationForSyncThread(false) |
| 804 , m_retainOrReleaseIconRequested(false) | 804 , m_retainOrReleaseIconRequested(false) |
| 805 , m_initialPruningComplete(false) | 805 , m_initialPruningComplete(false) |
| 806 , m_client(defaultClient()) | 806 , m_client(defaultClient()) |
| 807 { | 807 { |
| 808 LOG(IconDatabase, "Creating IconDatabase %p", this); | 808 LOG_INFO(IconDatabase, "Creating IconDatabase %p", this); |
| 809 ASSERT(isMainThread()); | 809 ASSERT(isMainThread()); |
| 810 } | 810 } |
| 811 | 811 |
| 812 IconDatabase::~IconDatabase() | 812 IconDatabase::~IconDatabase() |
| 813 { | 813 { |
| 814 ASSERT(!isOpen()); | 814 ASSERT(!isOpen()); |
| 815 } | 815 } |
| 816 | 816 |
| 817 void IconDatabase::notifyPendingLoadDecisionsOnMainThread(void* context) | 817 void IconDatabase::notifyPendingLoadDecisionsOnMainThread(void* context) |
| 818 { | 818 { |
| 819 static_cast<IconDatabase*>(context)->notifyPendingLoadDecisions(); | 819 static_cast<IconDatabase*>(context)->notifyPendingLoadDecisions(); |
| 820 } | 820 } |
| 821 | 821 |
| 822 void IconDatabase::notifyPendingLoadDecisions() | 822 void IconDatabase::notifyPendingLoadDecisions() |
| 823 { | 823 { |
| 824 ASSERT_NOT_SYNC_THREAD(); | 824 ASSERT_NOT_SYNC_THREAD(); |
| 825 | 825 |
| 826 // This method should only be called upon completion of the initial url impo
rt from the database | 826 // This method should only be called upon completion of the initial url impo
rt from the database |
| 827 ASSERT(m_iconURLImportComplete); | 827 ASSERT(m_iconURLImportComplete); |
| 828 LOG(IconDatabase, "Notifying all DocumentLoaders that were waiting on a load
decision for their icons"); | 828 LOG_INFO(IconDatabase, "Notifying all DocumentLoaders that were waiting on a
load decision for their icons"); |
| 829 | 829 |
| 830 HashSet<RefPtr<DocumentLoader> >::iterator i = m_loadersPendingDecision.begi
n(); | 830 HashSet<RefPtr<DocumentLoader> >::iterator i = m_loadersPendingDecision.begi
n(); |
| 831 HashSet<RefPtr<DocumentLoader> >::iterator end = m_loadersPendingDecision.en
d(); | 831 HashSet<RefPtr<DocumentLoader> >::iterator end = m_loadersPendingDecision.en
d(); |
| 832 | 832 |
| 833 for (; i != end; ++i) | 833 for (; i != end; ++i) |
| 834 if ((*i)->refCount() > 1) | 834 if ((*i)->refCount() > 1) |
| 835 (*i)->iconLoadDecisionAvailable(); | 835 (*i)->iconLoadDecisionAvailable(); |
| 836 | 836 |
| 837 m_loadersPendingDecision.clear(); | 837 m_loadersPendingDecision.clear(); |
| 838 } | 838 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 | 936 |
| 937 if (!documentCanHaveIcon(pageURL)) | 937 if (!documentCanHaveIcon(pageURL)) |
| 938 return 0; | 938 return 0; |
| 939 | 939 |
| 940 PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL); | 940 PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL); |
| 941 | 941 |
| 942 MutexLocker locker(m_pendingReadingLock); | 942 MutexLocker locker(m_pendingReadingLock); |
| 943 if (!m_iconURLImportComplete) { | 943 if (!m_iconURLImportComplete) { |
| 944 // If the initial import of all URLs hasn't completed and we have no pag
e record, we assume we *might* know about this later and create a record for it | 944 // If the initial import of all URLs hasn't completed and we have no pag
e record, we assume we *might* know about this later and create a record for it |
| 945 if (!pageRecord) { | 945 if (!pageRecord) { |
| 946 LOG(IconDatabase, "Creating new PageURLRecord for pageURL %s", urlFo
rLogging(pageURL).ascii().data()); | 946 LOG_INFO(IconDatabase, "Creating new PageURLRecord for pageURL %s",
urlForLogging(pageURL).ascii().data()); |
| 947 pageRecord = new PageURLRecord(pageURL); | 947 pageRecord = new PageURLRecord(pageURL); |
| 948 m_pageURLToRecordMap.set(pageURL, pageRecord); | 948 m_pageURLToRecordMap.set(pageURL, pageRecord); |
| 949 } | 949 } |
| 950 | 950 |
| 951 // If the pageRecord for this page does not have an iconRecord attached
to it, then it is a new pageRecord still awaiting the initial import | 951 // If the pageRecord for this page does not have an iconRecord attached
to it, then it is a new pageRecord still awaiting the initial import |
| 952 // Mark the URL as "interested in the result of the import" then bail | 952 // Mark the URL as "interested in the result of the import" then bail |
| 953 if (!pageRecord->iconRecord()) { | 953 if (!pageRecord->iconRecord()) { |
| 954 m_pageURLsPendingImport.add(pageURL); | 954 m_pageURLsPendingImport.add(pageURL); |
| 955 return 0; | 955 return 0; |
| 956 } | 956 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 983 { | 983 { |
| 984 // The call to create this thread might not complete before the thread actua
lly starts, so we might fail this ASSERT_ICON_SYNC_THREAD() because the pointer | 984 // The call to create this thread might not complete before the thread actua
lly starts, so we might fail this ASSERT_ICON_SYNC_THREAD() because the pointer |
| 985 // to our thread structure hasn't been filled in yet. | 985 // to our thread structure hasn't been filled in yet. |
| 986 // To fix this, the main thread acquires this lock before creating us, then
releases the lock after creation is complete. A quick lock/unlock cycle here wi
ll | 986 // To fix this, the main thread acquires this lock before creating us, then
releases the lock after creation is complete. A quick lock/unlock cycle here wi
ll |
| 987 // prevent us from running before that call completes | 987 // prevent us from running before that call completes |
| 988 m_syncLock.lock(); | 988 m_syncLock.lock(); |
| 989 m_syncLock.unlock(); | 989 m_syncLock.unlock(); |
| 990 | 990 |
| 991 ASSERT_ICON_SYNC_THREAD(); | 991 ASSERT_ICON_SYNC_THREAD(); |
| 992 | 992 |
| 993 LOG(IconDatabase, "(THREAD) IconDatabase sync thread started"); | 993 LOG_INFO(IconDatabase, "(THREAD) IconDatabase sync thread started"); |
| 994 | 994 |
| 995 #if !LOG_DISABLED | 995 #if !LOG_DISABLED |
| 996 double startTime = currentTime(); | 996 double startTime = currentTime(); |
| 997 #endif | 997 #endif |
| 998 | 998 |
| 999 // Need to create the database path if it doesn't already exist | 999 // Need to create the database path if it doesn't already exist |
| 1000 makeAllDirectories(m_databaseDirectory); | 1000 makeAllDirectories(m_databaseDirectory); |
| 1001 | 1001 |
| 1002 // Existence of a journal file is evidence of a previous crash/force quit an
d automatically qualifies | 1002 // Existence of a journal file is evidence of a previous crash/force quit an
d automatically qualifies |
| 1003 // us to do an integrity check | 1003 // us to do an integrity check |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1015 } | 1015 } |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 if (shouldStopThreadActivity()) { | 1018 if (shouldStopThreadActivity()) { |
| 1019 syncThreadMainLoop(); | 1019 syncThreadMainLoop(); |
| 1020 return; | 1020 return; |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 #if !LOG_DISABLED | 1023 #if !LOG_DISABLED |
| 1024 double timeStamp = currentTime(); | 1024 double timeStamp = currentTime(); |
| 1025 LOG(IconDatabase, "(THREAD) Open took %.4f seconds", timeStamp - startTime); | 1025 LOG_INFO(IconDatabase, "(THREAD) Open took %.4f seconds", timeStamp - startT
ime); |
| 1026 #endif | 1026 #endif |
| 1027 | 1027 |
| 1028 performOpenInitialization(); | 1028 performOpenInitialization(); |
| 1029 if (shouldStopThreadActivity()) { | 1029 if (shouldStopThreadActivity()) { |
| 1030 syncThreadMainLoop(); | 1030 syncThreadMainLoop(); |
| 1031 return; | 1031 return; |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 #if !LOG_DISABLED | 1034 #if !LOG_DISABLED |
| 1035 double newStamp = currentTime(); | 1035 double newStamp = currentTime(); |
| 1036 LOG(IconDatabase, "(THREAD) performOpenInitialization() took %.4f seconds, n
ow %.4f seconds from thread start", newStamp - timeStamp, newStamp - startTime); | 1036 LOG_INFO(IconDatabase, "(THREAD) performOpenInitialization() took %.4f secon
ds, now %.4f seconds from thread start", newStamp - timeStamp, newStamp - startT
ime); |
| 1037 timeStamp = newStamp; | 1037 timeStamp = newStamp; |
| 1038 #endif | 1038 #endif |
| 1039 | 1039 |
| 1040 // Uncomment the following line to simulate a long lasting URL import (*HUGE
* icon databases, or network home directories) | 1040 // Uncomment the following line to simulate a long lasting URL import (*HUGE
* icon databases, or network home directories) |
| 1041 // while (currentTime() - timeStamp < 10); | 1041 // while (currentTime() - timeStamp < 10); |
| 1042 | 1042 |
| 1043 // Read in URL mappings from the database | 1043 // Read in URL mappings from the database |
| 1044 LOG(IconDatabase, "(THREAD) Starting iconURL import"); | 1044 LOG_INFO(IconDatabase, "(THREAD) Starting iconURL import"); |
| 1045 performURLImport(); | 1045 performURLImport(); |
| 1046 | 1046 |
| 1047 if (shouldStopThreadActivity()) { | 1047 if (shouldStopThreadActivity()) { |
| 1048 syncThreadMainLoop(); | 1048 syncThreadMainLoop(); |
| 1049 return; | 1049 return; |
| 1050 } | 1050 } |
| 1051 | 1051 |
| 1052 #if !LOG_DISABLED | 1052 #if !LOG_DISABLED |
| 1053 newStamp = currentTime(); | 1053 newStamp = currentTime(); |
| 1054 LOG(IconDatabase, "(THREAD) performURLImport() took %.4f seconds. Entering
main loop %.4f seconds from thread start", newStamp - timeStamp, newStamp - star
tTime); | 1054 LOG_INFO(IconDatabase, "(THREAD) performURLImport() took %.4f seconds. Ente
ring main loop %.4f seconds from thread start", newStamp - timeStamp, newStamp -
startTime); |
| 1055 #endif | 1055 #endif |
| 1056 | 1056 |
| 1057 LOG(IconDatabase, "(THREAD) Beginning sync"); | 1057 LOG_INFO(IconDatabase, "(THREAD) Beginning sync"); |
| 1058 syncThreadMainLoop(); | 1058 syncThreadMainLoop(); |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 static int databaseVersionNumber(SQLiteDatabase& db) | 1061 static int databaseVersionNumber(SQLiteDatabase& db) |
| 1062 { | 1062 { |
| 1063 return SQLiteStatement(db, "SELECT value FROM IconDatabaseInfo WHERE key = '
Version';").getColumnInt(0); | 1063 return SQLiteStatement(db, "SELECT value FROM IconDatabaseInfo WHERE key = '
Version';").getColumnInt(0); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 static bool isValidDatabase(SQLiteDatabase& db) | 1066 static bool isValidDatabase(SQLiteDatabase& db) |
| 1067 { | 1067 { |
| 1068 // These four tables should always exist in a valid db | 1068 // These four tables should always exist in a valid db |
| 1069 if (!db.tableExists("IconInfo") || !db.tableExists("IconData") || !db.tableE
xists("PageURL") || !db.tableExists("IconDatabaseInfo")) | 1069 if (!db.tableExists("IconInfo") || !db.tableExists("IconData") || !db.tableE
xists("PageURL") || !db.tableExists("IconDatabaseInfo")) |
| 1070 return false; | 1070 return false; |
| 1071 | 1071 |
| 1072 if (databaseVersionNumber(db) < currentDatabaseVersion) { | 1072 if (databaseVersionNumber(db) < currentDatabaseVersion) { |
| 1073 LOG(IconDatabase, "DB version is not found or below expected valid versi
on"); | 1073 LOG_INFO(IconDatabase, "DB version is not found or below expected valid
version"); |
| 1074 return false; | 1074 return false; |
| 1075 } | 1075 } |
| 1076 | 1076 |
| 1077 return true; | 1077 return true; |
| 1078 } | 1078 } |
| 1079 | 1079 |
| 1080 static void createDatabaseTables(SQLiteDatabase& db) | 1080 static void createDatabaseTables(SQLiteDatabase& db) |
| 1081 { | 1081 { |
| 1082 if (!db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT
FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) { | 1082 if (!db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT
FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) { |
| 1083 LOG_ERROR("Could not create PageURL table in database (%i) - %s", db.las
tError(), db.lastErrorMsg()); | 1083 LOG_ERROR("Could not create PageURL table in database (%i) - %s", db.las
tError(), db.lastErrorMsg()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 void IconDatabase::performOpenInitialization() | 1124 void IconDatabase::performOpenInitialization() |
| 1125 { | 1125 { |
| 1126 ASSERT_ICON_SYNC_THREAD(); | 1126 ASSERT_ICON_SYNC_THREAD(); |
| 1127 | 1127 |
| 1128 if (!isOpen()) | 1128 if (!isOpen()) |
| 1129 return; | 1129 return; |
| 1130 | 1130 |
| 1131 if (checkIntegrityOnOpen) { | 1131 if (checkIntegrityOnOpen) { |
| 1132 checkIntegrityOnOpen = false; | 1132 checkIntegrityOnOpen = false; |
| 1133 if (!checkIntegrity()) { | 1133 if (!checkIntegrity()) { |
| 1134 LOG(IconDatabase, "Integrity check was bad - dumping IconDatabase"); | 1134 LOG_INFO(IconDatabase, "Integrity check was bad - dumping IconDataba
se"); |
| 1135 | 1135 |
| 1136 m_syncDB.close(); | 1136 m_syncDB.close(); |
| 1137 | 1137 |
| 1138 { | 1138 { |
| 1139 MutexLocker locker(m_syncLock); | 1139 MutexLocker locker(m_syncLock); |
| 1140 // Should've been consumed by SQLite, delete just to make sure w
e don't see it again in the future; | 1140 // Should've been consumed by SQLite, delete just to make sure w
e don't see it again in the future; |
| 1141 deleteFile(m_completeDatabasePath + "-journal"); | 1141 deleteFile(m_completeDatabasePath + "-journal"); |
| 1142 deleteFile(m_completeDatabasePath); | 1142 deleteFile(m_completeDatabasePath); |
| 1143 } | 1143 } |
| 1144 | 1144 |
| 1145 // Reopen the write database, creating it from scratch | 1145 // Reopen the write database, creating it from scratch |
| 1146 if (!m_syncDB.open(m_completeDatabasePath)) { | 1146 if (!m_syncDB.open(m_completeDatabasePath)) { |
| 1147 LOG_ERROR("Unable to open icon database at path %s - %s", m_comp
leteDatabasePath.ascii().data(), m_syncDB.lastErrorMsg()); | 1147 LOG_ERROR("Unable to open icon database at path %s - %s", m_comp
leteDatabasePath.ascii().data(), m_syncDB.lastErrorMsg()); |
| 1148 return; | 1148 return; |
| 1149 } | 1149 } |
| 1150 } | 1150 } |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 int version = databaseVersionNumber(m_syncDB); | 1153 int version = databaseVersionNumber(m_syncDB); |
| 1154 | 1154 |
| 1155 if (version > currentDatabaseVersion) { | 1155 if (version > currentDatabaseVersion) { |
| 1156 LOG(IconDatabase, "Database version number %i is greater than our curren
t version number %i - closing the database to prevent overwriting newer versions
", version, currentDatabaseVersion); | 1156 LOG_INFO(IconDatabase, "Database version number %i is greater than our c
urrent version number %i - closing the database to prevent overwriting newer ver
sions", version, currentDatabaseVersion); |
| 1157 m_syncDB.close(); | 1157 m_syncDB.close(); |
| 1158 m_threadTerminationRequested = true; | 1158 m_threadTerminationRequested = true; |
| 1159 return; | 1159 return; |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 if (!isValidDatabase(m_syncDB)) { | 1162 if (!isValidDatabase(m_syncDB)) { |
| 1163 LOG(IconDatabase, "%s is missing or in an invalid state - reconstructing
", m_completeDatabasePath.ascii().data()); | 1163 LOG_INFO(IconDatabase, "%s is missing or in an invalid state - reconstru
cting", m_completeDatabasePath.ascii().data()); |
| 1164 m_syncDB.clearAllTables(); | 1164 m_syncDB.clearAllTables(); |
| 1165 createDatabaseTables(m_syncDB); | 1165 createDatabaseTables(m_syncDB); |
| 1166 } | 1166 } |
| 1167 | 1167 |
| 1168 // Reduce sqlite RAM cache size from default 2000 pages (~1.5kB per page). 3
MB of cache for icon database is overkill | 1168 // Reduce sqlite RAM cache size from default 2000 pages (~1.5kB per page). 3
MB of cache for icon database is overkill |
| 1169 if (!SQLiteStatement(m_syncDB, "PRAGMA cache_size = 200;").executeCommand())
| 1169 if (!SQLiteStatement(m_syncDB, "PRAGMA cache_size = 200;").executeCommand())
|
| 1170 LOG_ERROR("SQLite database could not set cache_size"); | 1170 LOG_ERROR("SQLite database could not set cache_size"); |
| 1171 | 1171 |
| 1172 // Tell backup software (i.e., Time Machine) to never back up the icon datab
ase, because | 1172 // Tell backup software (i.e., Time Machine) to never back up the icon datab
ase, because |
| 1173 // it's a large file that changes frequently, thus using a lot of backup dis
k space, and | 1173 // it's a large file that changes frequently, thus using a lot of backup dis
k space, and |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 if (m_pageURLsPendingImport.contains(pageURL)) { | 1278 if (m_pageURLsPendingImport.contains(pageURL)) { |
| 1279 dispatchDidImportIconURLForPageURLOnMainThread(pageURL); | 1279 dispatchDidImportIconURLForPageURLOnMainThread(pageURL); |
| 1280 m_pageURLsPendingImport.remove(pageURL); | 1280 m_pageURLsPendingImport.remove(pageURL); |
| 1281 | 1281 |
| 1282 pool.cycle(); | 1282 pool.cycle(); |
| 1283 } | 1283 } |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 // Stop the import at any time of the thread has been asked to shutdown | 1286 // Stop the import at any time of the thread has been asked to shutdown |
| 1287 if (shouldStopThreadActivity()) { | 1287 if (shouldStopThreadActivity()) { |
| 1288 LOG(IconDatabase, "IconDatabase asked to terminate during performURL
Import()"); | 1288 LOG_INFO(IconDatabase, "IconDatabase asked to terminate during perfo
rmURLImport()"); |
| 1289 return; | 1289 return; |
| 1290 } | 1290 } |
| 1291 | 1291 |
| 1292 result = query.step(); | 1292 result = query.step(); |
| 1293 } | 1293 } |
| 1294 | 1294 |
| 1295 if (result != SQLResultDone) | 1295 if (result != SQLResultDone) |
| 1296 LOG(IconDatabase, "Error reading page->icon url mappings from database")
; | 1296 LOG_INFO(IconDatabase, "Error reading page->icon url mappings from datab
ase"); |
| 1297 | 1297 |
| 1298 // Clear the m_pageURLsPendingImport set - either the page URLs ended up wit
h an iconURL (that we'll notify about) or not, | 1298 // Clear the m_pageURLsPendingImport set - either the page URLs ended up wit
h an iconURL (that we'll notify about) or not, |
| 1299 // but after m_iconURLImportComplete is set to true, we don't care about thi
s set anymore | 1299 // but after m_iconURLImportComplete is set to true, we don't care about thi
s set anymore |
| 1300 Vector<String> urls; | 1300 Vector<String> urls; |
| 1301 { | 1301 { |
| 1302 MutexLocker locker(m_pendingReadingLock); | 1302 MutexLocker locker(m_pendingReadingLock); |
| 1303 | 1303 |
| 1304 urls.appendRange(m_pageURLsPendingImport.begin(), m_pageURLsPendingImpor
t.end()); | 1304 urls.appendRange(m_pageURLsPendingImport.begin(), m_pageURLsPendingImpor
t.end()); |
| 1305 m_pageURLsPendingImport.clear(); | 1305 m_pageURLsPendingImport.clear(); |
| 1306 m_iconURLImportComplete = true; | 1306 m_iconURLImportComplete = true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 delete record; | 1342 delete record; |
| 1343 } | 1343 } |
| 1344 } else { | 1344 } else { |
| 1345 urlsToNotify.append(urls[i]); | 1345 urlsToNotify.append(urls[i]); |
| 1346 } | 1346 } |
| 1347 } | 1347 } |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 LOG(IconDatabase, "Notifying %lu interested page URLs that their icon URL is
known due to the import", static_cast<unsigned long>(urlsToNotify.size())); | 1350 LOG_INFO(IconDatabase, "Notifying %lu interested page URLs that their icon U
RL is known due to the import", static_cast<unsigned long>(urlsToNotify.size()))
; |
| 1351 // Now that we don't hold any locks, perform the actual notifications | 1351 // Now that we don't hold any locks, perform the actual notifications |
| 1352 for (unsigned i = 0; i < urlsToNotify.size(); ++i) { | 1352 for (unsigned i = 0; i < urlsToNotify.size(); ++i) { |
| 1353 LOG(IconDatabase, "Notifying icon info known for pageURL %s", urlsToNoti
fy[i].ascii().data()); | 1353 LOG_INFO(IconDatabase, "Notifying icon info known for pageURL %s", urlsT
oNotify[i].ascii().data()); |
| 1354 dispatchDidImportIconURLForPageURLOnMainThread(urlsToNotify[i]); | 1354 dispatchDidImportIconURLForPageURLOnMainThread(urlsToNotify[i]); |
| 1355 if (shouldStopThreadActivity()) | 1355 if (shouldStopThreadActivity()) |
| 1356 return; | 1356 return; |
| 1357 | 1357 |
| 1358 pool.cycle(); | 1358 pool.cycle(); |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 // Notify the client that the URL import is complete in case it's managing i
ts own pending notifications. | 1361 // Notify the client that the URL import is complete in case it's managing i
ts own pending notifications. |
| 1362 dispatchDidFinishURLImportOnMainThread(); | 1362 dispatchDidFinishURLImportOnMainThread(); |
| 1363 | 1363 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1378 // without doing any work. Either way we're dealing with any currently-pendi
ng work. | 1378 // without doing any work. Either way we're dealing with any currently-pendi
ng work. |
| 1379 m_syncThreadHasWorkToDo = false; | 1379 m_syncThreadHasWorkToDo = false; |
| 1380 | 1380 |
| 1381 // It's possible thread termination is requested before the main loop even s
tarts - in that case, just skip straight to cleanup | 1381 // It's possible thread termination is requested before the main loop even s
tarts - in that case, just skip straight to cleanup |
| 1382 while (!m_threadTerminationRequested) { | 1382 while (!m_threadTerminationRequested) { |
| 1383 m_syncLock.unlock(); | 1383 m_syncLock.unlock(); |
| 1384 | 1384 |
| 1385 #if !LOG_DISABLED | 1385 #if !LOG_DISABLED |
| 1386 double timeStamp = currentTime(); | 1386 double timeStamp = currentTime(); |
| 1387 #endif | 1387 #endif |
| 1388 LOG(IconDatabase, "(THREAD) Main work loop starting"); | 1388 LOG_INFO(IconDatabase, "(THREAD) Main work loop starting"); |
| 1389 | 1389 |
| 1390 // If we should remove all icons, do it now. This is an uninteruptible
procedure that we will always do before quitting if it is requested | 1390 // If we should remove all icons, do it now. This is an uninteruptible
procedure that we will always do before quitting if it is requested |
| 1391 if (m_removeIconsRequested) { | 1391 if (m_removeIconsRequested) { |
| 1392 removeAllIconsOnThread(); | 1392 removeAllIconsOnThread(); |
| 1393 m_removeIconsRequested = false; | 1393 m_removeIconsRequested = false; |
| 1394 } | 1394 } |
| 1395 | 1395 |
| 1396 // Then, if the thread should be quitting, quit now! | 1396 // Then, if the thread should be quitting, quit now! |
| 1397 if (m_threadTerminationRequested) | 1397 if (m_threadTerminationRequested) |
| 1398 break; | 1398 break; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1416 // This way, pruning won't be the only operation we perform to the d
atabase by itself | 1416 // This way, pruning won't be the only operation we perform to the d
atabase by itself |
| 1417 // We also don't want to bother doing this if the thread should be t
erminating (the user is quitting) | 1417 // We also don't want to bother doing this if the thread should be t
erminating (the user is quitting) |
| 1418 // or if private browsing is enabled | 1418 // or if private browsing is enabled |
| 1419 // We also don't want to prune if the m_databaseCleanupCounter count
is non-zero - that means someone | 1419 // We also don't want to prune if the m_databaseCleanupCounter count
is non-zero - that means someone |
| 1420 // has asked to delay pruning | 1420 // has asked to delay pruning |
| 1421 static bool prunedUnretainedIcons = false; | 1421 static bool prunedUnretainedIcons = false; |
| 1422 if (didWrite && !m_privateBrowsingEnabled && !prunedUnretainedIcons
&& !databaseCleanupCounter) { | 1422 if (didWrite && !m_privateBrowsingEnabled && !prunedUnretainedIcons
&& !databaseCleanupCounter) { |
| 1423 #if !LOG_DISABLED | 1423 #if !LOG_DISABLED |
| 1424 double time = currentTime(); | 1424 double time = currentTime(); |
| 1425 #endif | 1425 #endif |
| 1426 LOG(IconDatabase, "(THREAD) Starting pruneUnretainedIcons()"); | 1426 LOG_INFO(IconDatabase, "(THREAD) Starting pruneUnretainedIcons()
"); |
| 1427 | 1427 |
| 1428 pruneUnretainedIcons(); | 1428 pruneUnretainedIcons(); |
| 1429 | 1429 |
| 1430 LOG(IconDatabase, "(THREAD) pruneUnretainedIcons() took %.4f sec
onds", currentTime() - time); | 1430 LOG_INFO(IconDatabase, "(THREAD) pruneUnretainedIcons() took %.4
f seconds", currentTime() - time); |
| 1431 | 1431 |
| 1432 // If pruneUnretainedIcons() returned early due to requested thr
ead termination, its still okay | 1432 // If pruneUnretainedIcons() returned early due to requested thr
ead termination, its still okay |
| 1433 // to mark prunedUnretainedIcons true because we're about to ter
minate anyway | 1433 // to mark prunedUnretainedIcons true because we're about to ter
minate anyway |
| 1434 prunedUnretainedIcons = true; | 1434 prunedUnretainedIcons = true; |
| 1435 } | 1435 } |
| 1436 | 1436 |
| 1437 didAnyWork = didAnyWork || didWrite; | 1437 didAnyWork = didAnyWork || didWrite; |
| 1438 if (shouldStopThreadActivity()) | 1438 if (shouldStopThreadActivity()) |
| 1439 break; | 1439 break; |
| 1440 } | 1440 } |
| 1441 | 1441 |
| 1442 #if !LOG_DISABLED | 1442 #if !LOG_DISABLED |
| 1443 double newstamp = currentTime(); | 1443 double newstamp = currentTime(); |
| 1444 LOG(IconDatabase, "(THREAD) Main work loop ran for %.4f seconds, %s requ
ested to terminate", newstamp - timeStamp, shouldStopThreadActivity() ? "was" :
"was not"); | 1444 LOG_INFO(IconDatabase, "(THREAD) Main work loop ran for %.4f seconds, %s
requested to terminate", newstamp - timeStamp, shouldStopThreadActivity() ? "wa
s" : "was not"); |
| 1445 #endif | 1445 #endif |
| 1446 | 1446 |
| 1447 m_syncLock.lock(); | 1447 m_syncLock.lock(); |
| 1448 | 1448 |
| 1449 // There is some condition that is asking us to stop what we're doing no
w and handle a special case | 1449 // There is some condition that is asking us to stop what we're doing no
w and handle a special case |
| 1450 // This is either removing all icons, or shutting down the thread to qui
t the app | 1450 // This is either removing all icons, or shutting down the thread to qui
t the app |
| 1451 // We handle those at the top of this main loop so continue to jump back
up there | 1451 // We handle those at the top of this main loop so continue to jump back
up there |
| 1452 if (shouldStopThreadActivity()) | 1452 if (shouldStopThreadActivity()) |
| 1453 continue; | 1453 continue; |
| 1454 | 1454 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 innerHash = &(icons[i]->retainingPageURLs()); | 1567 innerHash = &(icons[i]->retainingPageURLs()); |
| 1568 } else { | 1568 } else { |
| 1569 innerHash = &m_pageURLsInterestedInIcons; | 1569 innerHash = &m_pageURLsInterestedInIcons; |
| 1570 outerHash = &(icons[i]->retainingPageURLs()); | 1570 outerHash = &(icons[i]->retainingPageURLs()); |
| 1571 } | 1571 } |
| 1572 | 1572 |
| 1573 HashSet<String>::const_iterator iter = outerHash->begin(); | 1573 HashSet<String>::const_iterator iter = outerHash->begin(); |
| 1574 HashSet<String>::const_iterator end = outerHash->end(); | 1574 HashSet<String>::const_iterator end = outerHash->end(); |
| 1575 for (; iter != end; ++iter) { | 1575 for (; iter != end; ++iter) { |
| 1576 if (innerHash->contains(*iter)) { | 1576 if (innerHash->contains(*iter)) { |
| 1577 LOG(IconDatabase, "%s is interested in the icon we j
ust read. Adding it to the notification list and removing it from the interested
set", urlForLogging(*iter).ascii().data()); | 1577 LOG_INFO(IconDatabase, "%s is interested in the icon
we just read. Adding it to the notification list and removing it from the inter
ested set", urlForLogging(*iter).ascii().data()); |
| 1578 urlsToNotify.add(*iter); | 1578 urlsToNotify.add(*iter); |
| 1579 } | 1579 } |
| 1580 | 1580 |
| 1581 // If we ever get to the point were we've seen every url
interested in this icon, break early | 1581 // If we ever get to the point were we've seen every url
interested in this icon, break early |
| 1582 if (urlsToNotify.size() == m_pageURLsInterestedInIcons.s
ize()) | 1582 if (urlsToNotify.size() == m_pageURLsInterestedInIcons.s
ize()) |
| 1583 break; | 1583 break; |
| 1584 } | 1584 } |
| 1585 | 1585 |
| 1586 // We don't need to notify a PageURL twice, so all the ones
we're about to notify can be removed from the interested set | 1586 // We don't need to notify a PageURL twice, so all the ones
we're about to notify can be removed from the interested set |
| 1587 if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size(
)) | 1587 if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size(
)) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1600 return didAnyWork; | 1600 return didAnyWork; |
| 1601 | 1601 |
| 1602 // Informal testing shows that draining the autorelease pool every 25 it
erations is about as low as we can go | 1602 // Informal testing shows that draining the autorelease pool every 25 it
erations is about as low as we can go |
| 1603 // before performance starts to drop off, but we don't want to increase
this number because then accumulated memory usage will go up | 1603 // before performance starts to drop off, but we don't want to increase
this number because then accumulated memory usage will go up |
| 1604 AutodrainedPool pool(25); | 1604 AutodrainedPool pool(25); |
| 1605 | 1605 |
| 1606 // Now that we don't hold any locks, perform the actual notifications | 1606 // Now that we don't hold any locks, perform the actual notifications |
| 1607 HashSet<String>::iterator iter = urlsToNotify.begin(); | 1607 HashSet<String>::iterator iter = urlsToNotify.begin(); |
| 1608 HashSet<String>::iterator end = urlsToNotify.end(); | 1608 HashSet<String>::iterator end = urlsToNotify.end(); |
| 1609 for (unsigned iteration = 0; iter != end; ++iter, ++iteration) { | 1609 for (unsigned iteration = 0; iter != end; ++iter, ++iteration) { |
| 1610 LOG(IconDatabase, "Notifying icon received for pageURL %s", urlForLo
gging(*iter).ascii().data()); | 1610 LOG_INFO(IconDatabase, "Notifying icon received for pageURL %s", url
ForLogging(*iter).ascii().data()); |
| 1611 dispatchDidImportIconDataForPageURLOnMainThread(*iter); | 1611 dispatchDidImportIconDataForPageURLOnMainThread(*iter); |
| 1612 if (shouldStopThreadActivity()) | 1612 if (shouldStopThreadActivity()) |
| 1613 return didAnyWork; | 1613 return didAnyWork; |
| 1614 | 1614 |
| 1615 pool.cycle(); | 1615 pool.cycle(); |
| 1616 } | 1616 } |
| 1617 | 1617 |
| 1618 LOG(IconDatabase, "Done notifying %i pageURLs who just received their ic
ons", urlsToNotify.size()); | 1618 LOG_INFO(IconDatabase, "Done notifying %i pageURLs who just received the
ir icons", urlsToNotify.size()); |
| 1619 urlsToNotify.clear(); | 1619 urlsToNotify.clear(); |
| 1620 | 1620 |
| 1621 if (shouldStopThreadActivity()) | 1621 if (shouldStopThreadActivity()) |
| 1622 return didAnyWork; | 1622 return didAnyWork; |
| 1623 } | 1623 } |
| 1624 | 1624 |
| 1625 LOG(IconDatabase, "Reading from database took %.4f seconds", currentTime() -
timeStamp); | 1625 LOG_INFO(IconDatabase, "Reading from database took %.4f seconds", currentTim
e() - timeStamp); |
| 1626 | 1626 |
| 1627 return didAnyWork; | 1627 return didAnyWork; |
| 1628 } | 1628 } |
| 1629 | 1629 |
| 1630 bool IconDatabase::writeToDatabase() | 1630 bool IconDatabase::writeToDatabase() |
| 1631 { | 1631 { |
| 1632 ASSERT_ICON_SYNC_THREAD(); | 1632 ASSERT_ICON_SYNC_THREAD(); |
| 1633 | 1633 |
| 1634 #if !LOG_DISABLED | 1634 #if !LOG_DISABLED |
| 1635 double timeStamp = currentTime(); | 1635 double timeStamp = currentTime(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1655 } | 1655 } |
| 1656 | 1656 |
| 1657 if (iconSnapshots.size() || pageSnapshots.size()) | 1657 if (iconSnapshots.size() || pageSnapshots.size()) |
| 1658 didAnyWork = true; | 1658 didAnyWork = true; |
| 1659 | 1659 |
| 1660 SQLiteTransaction syncTransaction(m_syncDB); | 1660 SQLiteTransaction syncTransaction(m_syncDB); |
| 1661 syncTransaction.begin(); | 1661 syncTransaction.begin(); |
| 1662 | 1662 |
| 1663 for (unsigned i = 0; i < iconSnapshots.size(); ++i) { | 1663 for (unsigned i = 0; i < iconSnapshots.size(); ++i) { |
| 1664 writeIconSnapshotToSQLDatabase(iconSnapshots[i]); | 1664 writeIconSnapshotToSQLDatabase(iconSnapshots[i]); |
| 1665 LOG(IconDatabase, "Wrote IconRecord for IconURL %s with timeStamp of
%i to the DB", urlForLogging(iconSnapshots[i].iconURL()).ascii().data(), iconSn
apshots[i].timestamp()); | 1665 LOG_INFO(IconDatabase, "Wrote IconRecord for IconURL %s with timeSta
mp of %i to the DB", urlForLogging(iconSnapshots[i].iconURL()).ascii().data(), i
conSnapshots[i].timestamp()); |
| 1666 } | 1666 } |
| 1667 | 1667 |
| 1668 for (unsigned i = 0; i < pageSnapshots.size(); ++i) { | 1668 for (unsigned i = 0; i < pageSnapshots.size(); ++i) { |
| 1669 // If the icon URL is empty, this page is meant to be deleted | 1669 // If the icon URL is empty, this page is meant to be deleted |
| 1670 // ASSERTs are sanity checks to make sure the mappings exist if they
should and don't if they shouldn't | 1670 // ASSERTs are sanity checks to make sure the mappings exist if they
should and don't if they shouldn't |
| 1671 if (pageSnapshots[i].iconURL().isEmpty()) | 1671 if (pageSnapshots[i].iconURL().isEmpty()) |
| 1672 removePageURLFromSQLDatabase(pageSnapshots[i].pageURL()); | 1672 removePageURLFromSQLDatabase(pageSnapshots[i].pageURL()); |
| 1673 else | 1673 else |
| 1674 setIconURLForPageURLInSQLDatabase(pageSnapshots[i].iconURL(), pa
geSnapshots[i].pageURL()); | 1674 setIconURLForPageURLInSQLDatabase(pageSnapshots[i].iconURL(), pa
geSnapshots[i].pageURL()); |
| 1675 LOG(IconDatabase, "Committed IconURL for PageURL %s to database", ur
lForLogging(pageSnapshots[i].pageURL()).ascii().data()); | 1675 LOG_INFO(IconDatabase, "Committed IconURL for PageURL %s to database
", urlForLogging(pageSnapshots[i].pageURL()).ascii().data()); |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 syncTransaction.commit(); | 1678 syncTransaction.commit(); |
| 1679 } | 1679 } |
| 1680 | 1680 |
| 1681 // Check to make sure there are no dangling PageURLs - If there are, we want
to output one log message but not spam the console potentially every few second
s | 1681 // Check to make sure there are no dangling PageURLs - If there are, we want
to output one log message but not spam the console potentially every few second
s |
| 1682 if (didAnyWork) | 1682 if (didAnyWork) |
| 1683 checkForDanglingPageURLs(false); | 1683 checkForDanglingPageURLs(false); |
| 1684 | 1684 |
| 1685 LOG(IconDatabase, "Updating the database took %.4f seconds", currentTime() -
timeStamp); | 1685 LOG_INFO(IconDatabase, "Updating the database took %.4f seconds", currentTim
e() - timeStamp); |
| 1686 | 1686 |
| 1687 return didAnyWork; | 1687 return didAnyWork; |
| 1688 } | 1688 } |
| 1689 | 1689 |
| 1690 void IconDatabase::pruneUnretainedIcons() | 1690 void IconDatabase::pruneUnretainedIcons() |
| 1691 { | 1691 { |
| 1692 ASSERT_ICON_SYNC_THREAD(); | 1692 ASSERT_ICON_SYNC_THREAD(); |
| 1693 | 1693 |
| 1694 if (!isOpen()) | 1694 if (!isOpen()) |
| 1695 return; | 1695 return; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1720 // Delete page URLs that were in the table, but not in our retain count set. | 1720 // Delete page URLs that were in the table, but not in our retain count set. |
| 1721 size_t numToDelete = pageIDsToDelete.size(); | 1721 size_t numToDelete = pageIDsToDelete.size(); |
| 1722 if (numToDelete) { | 1722 if (numToDelete) { |
| 1723 SQLiteTransaction pruningTransaction(m_syncDB); | 1723 SQLiteTransaction pruningTransaction(m_syncDB); |
| 1724 pruningTransaction.begin(); | 1724 pruningTransaction.begin(); |
| 1725 | 1725 |
| 1726 SQLiteStatement pageDeleteSQL(m_syncDB, "DELETE FROM PageURL WHERE rowid
= (?);"); | 1726 SQLiteStatement pageDeleteSQL(m_syncDB, "DELETE FROM PageURL WHERE rowid
= (?);"); |
| 1727 pageDeleteSQL.prepare(); | 1727 pageDeleteSQL.prepare(); |
| 1728 for (size_t i = 0; i < numToDelete; ++i) { | 1728 for (size_t i = 0; i < numToDelete; ++i) { |
| 1729 #if OS(WINDOWS) | 1729 #if OS(WINDOWS) |
| 1730 LOG(IconDatabase, "Pruning page with rowid %I64i from disk", static_
cast<long long>(pageIDsToDelete[i])); | 1730 LOG_INFO(IconDatabase, "Pruning page with rowid %I64i from disk", st
atic_cast<long long>(pageIDsToDelete[i])); |
| 1731 #else | 1731 #else |
| 1732 LOG(IconDatabase, "Pruning page with rowid %lli from disk", static_c
ast<long long>(pageIDsToDelete[i])); | 1732 LOG_INFO(IconDatabase, "Pruning page with rowid %lli from disk", sta
tic_cast<long long>(pageIDsToDelete[i])); |
| 1733 #endif | 1733 #endif |
| 1734 pageDeleteSQL.bindInt64(1, pageIDsToDelete[i]); | 1734 pageDeleteSQL.bindInt64(1, pageIDsToDelete[i]); |
| 1735 int result = pageDeleteSQL.step(); | 1735 int result = pageDeleteSQL.step(); |
| 1736 if (result != SQLResultDone) | 1736 if (result != SQLResultDone) |
| 1737 #if OS(WINDOWS) | 1737 #if OS(WINDOWS) |
| 1738 LOG_ERROR("Unabled to delete page with id %I64i from disk", stat
ic_cast<long long>(pageIDsToDelete[i])); | 1738 LOG_ERROR("Unabled to delete page with id %I64i from disk", stat
ic_cast<long long>(pageIDsToDelete[i])); |
| 1739 #else | 1739 #else |
| 1740 LOG_ERROR("Unabled to delete page with id %lli from disk", stati
c_cast<long long>(pageIDsToDelete[i])); | 1740 LOG_ERROR("Unabled to delete page with id %lli from disk", stati
c_cast<long long>(pageIDsToDelete[i])); |
| 1741 #endif | 1741 #endif |
| 1742 pageDeleteSQL.reset(); | 1742 pageDeleteSQL.reset(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 // entries. We also don't want to keep performing this check and reporting
this error if it has already found danglers before so we | 1780 // entries. We also don't want to keep performing this check and reporting
this error if it has already found danglers before so we |
| 1781 // keep track of whether we've found any. We skip the check in the release
build pretending to have already found danglers already. | 1781 // keep track of whether we've found any. We skip the check in the release
build pretending to have already found danglers already. |
| 1782 #ifndef NDEBUG | 1782 #ifndef NDEBUG |
| 1783 static bool danglersFound = true; | 1783 static bool danglersFound = true; |
| 1784 #else | 1784 #else |
| 1785 static bool danglersFound = false; | 1785 static bool danglersFound = false; |
| 1786 #endif | 1786 #endif |
| 1787 | 1787 |
| 1788 if ((pruneIfFound || !danglersFound) && SQLiteStatement(m_syncDB, "SELECT ur
l FROM PageURL WHERE PageURL.iconID NOT IN (SELECT iconID FROM IconInfo) LIMIT 1
;").returnsAtLeastOneResult()) { | 1788 if ((pruneIfFound || !danglersFound) && SQLiteStatement(m_syncDB, "SELECT ur
l FROM PageURL WHERE PageURL.iconID NOT IN (SELECT iconID FROM IconInfo) LIMIT 1
;").returnsAtLeastOneResult()) { |
| 1789 danglersFound = true; | 1789 danglersFound = true; |
| 1790 LOG(IconDatabase, "Dangling PageURL entries found"); | 1790 LOG_INFO(IconDatabase, "Dangling PageURL entries found"); |
| 1791 if (pruneIfFound && !m_syncDB.executeCommand("DELETE FROM PageURL WHERE
iconID NOT IN (SELECT iconID FROM IconInfo);")) | 1791 if (pruneIfFound && !m_syncDB.executeCommand("DELETE FROM PageURL WHERE
iconID NOT IN (SELECT iconID FROM IconInfo);")) |
| 1792 LOG(IconDatabase, "Unable to prune dangling PageURLs"); | 1792 LOG_INFO(IconDatabase, "Unable to prune dangling PageURLs"); |
| 1793 } | 1793 } |
| 1794 } | 1794 } |
| 1795 | 1795 |
| 1796 void IconDatabase::removeAllIconsOnThread() | 1796 void IconDatabase::removeAllIconsOnThread() |
| 1797 { | 1797 { |
| 1798 ASSERT_ICON_SYNC_THREAD(); | 1798 ASSERT_ICON_SYNC_THREAD(); |
| 1799 | 1799 |
| 1800 LOG(IconDatabase, "Removing all icons on the sync thread"); | 1800 LOG_INFO(IconDatabase, "Removing all icons on the sync thread"); |
| 1801 | 1801 |
| 1802 // Delete all the prepared statements so they can start over | 1802 // Delete all the prepared statements so they can start over |
| 1803 deleteAllPreparedStatements(); | 1803 deleteAllPreparedStatements(); |
| 1804 | 1804 |
| 1805 // To reset the on-disk database, we'll wipe all its tables then vacuum it | 1805 // To reset the on-disk database, we'll wipe all its tables then vacuum it |
| 1806 // This is easier and safer than closing it, deleting the file, and recreati
ng from scratch | 1806 // This is easier and safer than closing it, deleting the file, and recreati
ng from scratch |
| 1807 m_syncDB.clearAllTables(); | 1807 m_syncDB.clearAllTables(); |
| 1808 m_syncDB.runVacuumCommand(); | 1808 m_syncDB.runVacuumCommand(); |
| 1809 createDatabaseTables(m_syncDB); | 1809 createDatabaseTables(m_syncDB); |
| 1810 | 1810 |
| 1811 LOG(IconDatabase, "Dispatching notification that we removed all icons"); | 1811 LOG_INFO(IconDatabase, "Dispatching notification that we removed all icons")
; |
| 1812 dispatchDidRemoveAllIconsOnMainThread(); | 1812 dispatchDidRemoveAllIconsOnMainThread(); |
| 1813 } | 1813 } |
| 1814 | 1814 |
| 1815 void IconDatabase::deleteAllPreparedStatements() | 1815 void IconDatabase::deleteAllPreparedStatements() |
| 1816 { | 1816 { |
| 1817 ASSERT_ICON_SYNC_THREAD(); | 1817 ASSERT_ICON_SYNC_THREAD(); |
| 1818 | 1818 |
| 1819 m_setIconIDForPageURLStatement.clear(); | 1819 m_setIconIDForPageURLStatement.clear(); |
| 1820 m_removePageURLStatement.clear(); | 1820 m_removePageURLStatement.clear(); |
| 1821 m_getIconIDForIconURLStatement.clear(); | 1821 m_getIconIDForIconURLStatement.clear(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1838 | 1838 |
| 1839 #if !LOG_DISABLED | 1839 #if !LOG_DISABLED |
| 1840 double timeStamp = currentTime(); | 1840 double timeStamp = currentTime(); |
| 1841 #endif | 1841 #endif |
| 1842 | 1842 |
| 1843 // If the removeIcons flag is set, remove all icons from the db. | 1843 // If the removeIcons flag is set, remove all icons from the db. |
| 1844 if (m_removeIconsRequested) | 1844 if (m_removeIconsRequested) |
| 1845 removeAllIconsOnThread(); | 1845 removeAllIconsOnThread(); |
| 1846 | 1846 |
| 1847 // Sync remaining icons out | 1847 // Sync remaining icons out |
| 1848 LOG(IconDatabase, "(THREAD) Doing final writeout and closure of sync thread"
); | 1848 LOG_INFO(IconDatabase, "(THREAD) Doing final writeout and closure of sync th
read"); |
| 1849 writeToDatabase(); | 1849 writeToDatabase(); |
| 1850 | 1850 |
| 1851 // Close the database | 1851 // Close the database |
| 1852 MutexLocker locker(m_syncLock); | 1852 MutexLocker locker(m_syncLock); |
| 1853 | 1853 |
| 1854 m_databaseDirectory = String(); | 1854 m_databaseDirectory = String(); |
| 1855 m_completeDatabasePath = String(); | 1855 m_completeDatabasePath = String(); |
| 1856 deleteAllPreparedStatements(); | 1856 deleteAllPreparedStatements(); |
| 1857 m_syncDB.close(); | 1857 m_syncDB.close(); |
| 1858 | 1858 |
| 1859 #if !LOG_DISABLED | 1859 #if !LOG_DISABLED |
| 1860 LOG(IconDatabase, "(THREAD) Final closure took %.4f seconds", currentTime()
- timeStamp); | 1860 LOG_INFO(IconDatabase, "(THREAD) Final closure took %.4f seconds", currentTi
me() - timeStamp); |
| 1861 #endif | 1861 #endif |
| 1862 | 1862 |
| 1863 m_syncThreadRunning = false; | 1863 m_syncThreadRunning = false; |
| 1864 return 0; | 1864 return 0; |
| 1865 } | 1865 } |
| 1866 | 1866 |
| 1867 // readySQLiteStatement() handles two things | 1867 // readySQLiteStatement() handles two things |
| 1868 // 1 - If the SQLDatabase& argument is different, the statement must be destroye
d and remade. This happens when the user | 1868 // 1 - If the SQLDatabase& argument is different, the statement must be destroye
d and remade. This happens when the user |
| 1869 // switches to and from private browsing | 1869 // switches to and from private browsing |
| 1870 // 2 - Lazy construction of the Statement in the first place, in case we've neve
r made this query before | 1870 // 2 - Lazy construction of the Statement in the first place, in case we've neve
r made this query before |
| 1871 inline void readySQLiteStatement(OwnPtr<SQLiteStatement>& statement, SQLiteDatab
ase& db, const String& str) | 1871 inline void readySQLiteStatement(OwnPtr<SQLiteStatement>& statement, SQLiteDatab
ase& db, const String& str) |
| 1872 { | 1872 { |
| 1873 if (statement && (statement->database() != &db || statement->isExpired())) { | 1873 if (statement && (statement->database() != &db || statement->isExpired())) { |
| 1874 if (statement->isExpired()) | 1874 if (statement->isExpired()) |
| 1875 LOG(IconDatabase, "SQLiteStatement associated with %s is expired", s
tr.ascii().data()); | 1875 LOG_INFO(IconDatabase, "SQLiteStatement associated with %s is expire
d", str.ascii().data()); |
| 1876 statement.clear(); | 1876 statement.clear(); |
| 1877 } | 1877 } |
| 1878 if (!statement) { | 1878 if (!statement) { |
| 1879 statement = adoptPtr(new SQLiteStatement(db, str)); | 1879 statement = adoptPtr(new SQLiteStatement(db, str)); |
| 1880 if (statement->prepare() != SQLResultOk) | 1880 if (statement->prepare() != SQLResultOk) |
| 1881 LOG_ERROR("Preparing statement %s failed", str.ascii().data()); | 1881 LOG_ERROR("Preparing statement %s failed", str.ascii().data()); |
| 1882 } | 1882 } |
| 1883 } | 1883 } |
| 1884 | 1884 |
| 1885 void IconDatabase::setIconURLForPageURLInSQLDatabase(const String& iconURL, cons
t String& pageURL) | 1885 void IconDatabase::setIconURLForPageURLInSQLDatabase(const String& iconURL, cons
t String& pageURL) |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2046 | 2046 |
| 2047 void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot) | 2047 void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot) |
| 2048 { | 2048 { |
| 2049 ASSERT_ICON_SYNC_THREAD(); | 2049 ASSERT_ICON_SYNC_THREAD(); |
| 2050 | 2050 |
| 2051 if (snapshot.iconURL().isEmpty()) | 2051 if (snapshot.iconURL().isEmpty()) |
| 2052 return; | 2052 return; |
| 2053 | 2053 |
| 2054 // A nulled out timestamp and data means this icon is destined to be deleted
- do that instead of writing it out | 2054 // A nulled out timestamp and data means this icon is destined to be deleted
- do that instead of writing it out |
| 2055 if (!snapshot.timestamp() && !snapshot.data()) { | 2055 if (!snapshot.timestamp() && !snapshot.data()) { |
| 2056 LOG(IconDatabase, "Removing %s from on-disk database", urlForLogging(sna
pshot.iconURL()).ascii().data()); | 2056 LOG_INFO(IconDatabase, "Removing %s from on-disk database", urlForLoggin
g(snapshot.iconURL()).ascii().data()); |
| 2057 removeIconFromSQLDatabase(snapshot.iconURL()); | 2057 removeIconFromSQLDatabase(snapshot.iconURL()); |
| 2058 return; | 2058 return; |
| 2059 } | 2059 } |
| 2060 | 2060 |
| 2061 // There would be a transaction here to make sure these removals are atomic | 2061 // There would be a transaction here to make sure these removals are atomic |
| 2062 // In practice the only caller of this method is always wrapped in a transac
tion itself so placing another here is unnecessary | 2062 // In practice the only caller of this method is always wrapped in a transac
tion itself so placing another here is unnecessary |
| 2063 | 2063 |
| 2064 // Get the iconID for this url | 2064 // Get the iconID for this url |
| 2065 int64_t iconID = getIconIDForIconURLFromSQLDatabase(snapshot.iconURL()); | 2065 int64_t iconID = getIconIDForIconURLFromSQLDatabase(snapshot.iconURL()); |
| 2066 | 2066 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2257 ASSERT_ICON_SYNC_THREAD(); | 2257 ASSERT_ICON_SYNC_THREAD(); |
| 2258 | 2258 |
| 2259 FinishedURLImport* work = new FinishedURLImport(m_client); | 2259 FinishedURLImport* work = new FinishedURLImport(m_client); |
| 2260 callOnMainThread(performWorkItem, work); | 2260 callOnMainThread(performWorkItem, work); |
| 2261 } | 2261 } |
| 2262 | 2262 |
| 2263 | 2263 |
| 2264 } // namespace WebCore | 2264 } // namespace WebCore |
| 2265 | 2265 |
| 2266 #endif // ENABLE(ICONDATABASE) | 2266 #endif // ENABLE(ICONDATABASE) |
| OLD | NEW |