[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

levin at chromium.org levin at chromium.org
Thu Oct 29 20:39:53 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit bcb91543861447370bde00c7c13247cb2deb5061
Author: levin at chromium.org <levin at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Oct 6 07:45:09 2009 +0000

    StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer.
    https://bugs.webkit.org/show_bug.cgi?id=30095
    
    Patch by David Levin <levin at chromium.org> on 2009-10-06
    Reviewed by Oliver Hunt.
    
    JavaScriptCore:
    
    * wtf/CrossThreadRefCounted.h:
    Removed an unused function and assert improvement.
    (WTF::CrossThreadRefCounted::isOwnedByCurrentThread): Moved out common code from asserts.
    (WTF::CrossThreadRefCounted::ref): Changed assert to use the common method.
    (WTF::CrossThreadRefCounted::deref): Changed assert to use the common method.
    (WTF::CrossThreadRefCounted::crossThreadCopy): Since this includes a potentially
    non-threadsafe operation, add an assert that the class is owned by the current thread.
    
    WebCore:
    
    All String::copy methods were changed to call either threadsafeCopy or crossThreadString. The method
    call was made threadsafeCopy unless I could show that threadsafety wasn't needed.
    
    No visible change in functionality so no new tests.
    
    * dom/MessagePortChannel.cpp:
    (WebCore::MessagePortChannel::EventData::EventData):
    * loader/WorkerThreadableLoader.cpp:
    (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
    * loader/icon/IconDatabase.cpp:
    (WebCore::IconDatabase::open):
    (WebCore::IconDatabase::iconForPageURL):
    (WebCore::IconDatabase::iconURLForPageURL):
    (WebCore::IconDatabase::retainIconForPageURL):
    (WebCore::IconDatabase::releaseIconForPageURL):
    (WebCore::IconDatabase::setIconDataForIconURL):
    (WebCore::IconDatabase::setIconURLForPageURL):
    (WebCore::IconDatabase::databasePath):
    (WebCore::IconDatabase::defaultDatabaseFilename):
    * page/SecurityOrigin.cpp:
    (WebCore::SecurityOrigin::SecurityOrigin): Since this is used by SecurityOrigin::threadsafeCopy,
    it makes threadsafe calls.
    (WebCore::SecurityOrigin::threadsafeCopy): The only place that called this
    needed a threadsafe method.
    * page/SecurityOrigin.h:
    * platform/CrossThreadCopier.cpp:
    (WebCore::::copy):
    * platform/KURL.cpp:
    (WebCore::KURL::copy):
    * platform/network/HTTPHeaderMap.cpp:
    (WebCore::HTTPHeaderMap::copyData):
    * platform/network/ResourceErrorBase.cpp:
    (WebCore::ResourceErrorBase::copy):
    * platform/network/ResourceRequestBase.cpp:
    (WebCore::ResourceRequestBase::copyData):
    * platform/network/ResourceResponseBase.cpp:
    (WebCore::ResourceResponseBase::copyData):
    * platform/sql/SQLValue.cpp:
    (WebCore::SQLValue::SQLValue):
    (WebCore::SQLValue::string):
    * platform/sql/SQLValue.h:
    (WebCore::SQLValue::SQLValue):
    All constructors now initialize the m_number which is a double. Failure to
    do so can result in unexpected crashes when it is copied in the copy constructor.
    See http://blogs.msdn.com/oldnewthing/archive/2008/07/02/8679191.aspx, I was that colleague.
    * platform/text/PlatformString.h:
    * platform/text/String.cpp:
    (WebCore::String::threadsafeCopy):
    (WebCore::String::crossThreadString):
    * platform/text/StringImpl.cpp:
    Removed StringImpl::substringCopy which was no longer being used anywhere.
    (WebCore::StringImpl::threadsafeCopy): Changed the name to indicate that
    it is threadsafe.
    (WebCore::StringImpl::crossThreadString): The way to get strings for
    another thread which is not threadsafe. This shares the underlying buffer
    with both strings and gives them a way to do threadsafe refcounting for it.
    * platform/text/StringImpl.h:
    * storage/ChangeVersionWrapper.cpp:
    (WebCore::ChangeVersionWrapper::ChangeVersionWrapper):
    * storage/Database.cpp:
    (WebCore::updateGuidVersionMap):
    (WebCore::Database::Database):
    (WebCore::Database::getVersionFromDatabase):
    (WebCore::Database::setVersionInDatabase):
    (WebCore::Database::version):
    (WebCore::Database::setExpectedVersion):
    (WebCore::Database::securityOriginCopy):
    (WebCore::Database::stringIdentifier):
    * storage/DatabaseTracker.cpp:
    (WebCore::DatabaseTracker::scheduleNotifyDatabaseChanged):
    * storage/OriginQuotaManager.cpp:
    (WebCore::OriginQuotaManager::addDatabase):
    * storage/SQLError.h:
    (WebCore::SQLError::message):
    (WebCore::SQLError::SQLError):
    * storage/SQLStatement.cpp:
    (WebCore::SQLStatement::SQLStatement):
    * storage/StorageAreaSync.cpp:
    (WebCore::StorageAreaSync::syncTimerFired):
    * storage/StorageMap.cpp:
    (WebCore::StorageMap::importItem):
    * storage/StorageNamespaceImpl.cpp:
    (WebCore::StorageNamespaceImpl::StorageNamespaceImpl):
    * storage/StorageSyncManager.cpp:
    (WebCore::StorageSyncManager::StorageSyncManager):
    * workers/DefaultSharedWorkerRepository.cpp:
    (WebCore::SharedWorkerProxy::url): Do the copy of the url in a way that is threadsafe.
    (WebCore::SharedWorkerProxy::name):
    (WebCore::SharedWorkerProxy::SharedWorkerProxy):
    (WebCore::DefaultSharedWorkerRepository::getProxy): Do the copy of the url in a way that is threadsafe.
    * workers/SharedWorkerThread.cpp:
    (WebCore::SharedWorkerThread::SharedWorkerThread):
    * workers/WorkerMessagingProxy.cpp:
    (WebCore::MessageWorkerContextTask::MessageWorkerContextTask):
    (WebCore::MessageWorkerTask::MessageWorkerTask):
    (WebCore::WorkerExceptionTask::WorkerExceptionTask):
    * workers/WorkerRunLoop.cpp:
    (WebCore::WorkerRunLoop::Task::Task):
    (WebCore::WorkerRunLoop::postTaskForMode):
    * workers/WorkerThread.cpp:
    (WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49160 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 51a496b..aea99c9 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
+2009-10-06  David Levin  <levin at chromium.org>
+
+        Reviewed by Oliver Hunt.
+
+        StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer.
+        https://bugs.webkit.org/show_bug.cgi?id=30095
+
+        * wtf/CrossThreadRefCounted.h:
+        Removed an unused function and assert improvement.
+        (WTF::CrossThreadRefCounted::isOwnedByCurrentThread): Moved out common code from asserts.
+        (WTF::CrossThreadRefCounted::ref): Changed assert to use the common method.
+        (WTF::CrossThreadRefCounted::deref): Changed assert to use the common method.
+        (WTF::CrossThreadRefCounted::crossThreadCopy): Since this includes a potentially
+        non-threadsafe operation, add an assert that the class is owned by the current thread.
+
 2009-10-05  Kevin Ollivier  <kevino at theolliviers.com>
 
         wx build fix. Add Symbian files to the list of excludes.
diff --git a/JavaScriptCore/wtf/CrossThreadRefCounted.h b/JavaScriptCore/wtf/CrossThreadRefCounted.h
index 6a05211..f682f0d 100644
--- a/JavaScriptCore/wtf/CrossThreadRefCounted.h
+++ b/JavaScriptCore/wtf/CrossThreadRefCounted.h
@@ -70,10 +70,6 @@ namespace WTF {
             return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef());
         }
 
-#ifndef NDEBUG
-        bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); }
-#endif
-
     private:
         CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
             : m_threadSafeRefCounter(threadedCounter)
@@ -92,6 +88,10 @@ namespace WTF {
 
         void threadSafeDeref();
 
+#ifndef NDEBUG
+        bool isOwnedByCurrentThread() const { return !m_threadId || m_threadId == currentThread(); }
+#endif
+
         RefCountedBase m_refCounter;
         ThreadSafeSharedBase* m_threadSafeRefCounter;
         T* m_data;
@@ -103,7 +103,7 @@ namespace WTF {
     template<class T>
     void CrossThreadRefCounted<T>::ref()
     {
-        ASSERT(!m_threadId || m_threadId == currentThread());
+        ASSERT(isOwnedByCurrentThread());
         m_refCounter.ref();
 #ifndef NDEBUG
         // Store the threadId as soon as the ref count gets to 2.
@@ -119,7 +119,7 @@ namespace WTF {
     template<class T>
     void CrossThreadRefCounted<T>::deref()
     {
-        ASSERT(!m_threadId || m_threadId == currentThread());
+        ASSERT(isOwnedByCurrentThread());
         if (m_refCounter.derefBase()) {
             threadSafeDeref();
             delete this;
@@ -146,10 +146,12 @@ namespace WTF {
     template<class T>
     PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy()
     {
+        ASSERT(isOwnedByCurrentThread());
         if (m_threadSafeRefCounter)
             m_threadSafeRefCounter->ref();
         else
             m_threadSafeRefCounter = new ThreadSafeSharedBase(2);
+
         return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter));
     }
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 58d8287..99ebe4a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,112 @@
+2009-10-06  David Levin  <levin at chromium.org>
+
+        Reviewed by Oliver Hunt.
+
+        StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer.
+        https://bugs.webkit.org/show_bug.cgi?id=30095
+
+        All String::copy methods were changed to call either threadsafeCopy or crossThreadString. The method
+        call was made threadsafeCopy unless I could show that threadsafety wasn't needed.
+
+        No visible change in functionality so no new tests.
+
+        * dom/MessagePortChannel.cpp:
+        (WebCore::MessagePortChannel::EventData::EventData):
+        * loader/WorkerThreadableLoader.cpp:
+        (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+        * loader/icon/IconDatabase.cpp:
+        (WebCore::IconDatabase::open):
+        (WebCore::IconDatabase::iconForPageURL):
+        (WebCore::IconDatabase::iconURLForPageURL):
+        (WebCore::IconDatabase::retainIconForPageURL):
+        (WebCore::IconDatabase::releaseIconForPageURL):
+        (WebCore::IconDatabase::setIconDataForIconURL):
+        (WebCore::IconDatabase::setIconURLForPageURL):
+        (WebCore::IconDatabase::databasePath):
+        (WebCore::IconDatabase::defaultDatabaseFilename):
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::SecurityOrigin): Since this is used by SecurityOrigin::threadsafeCopy,
+        it makes threadsafe calls.
+        (WebCore::SecurityOrigin::threadsafeCopy): The only place that called this
+        needed a threadsafe method.
+        * page/SecurityOrigin.h:
+        * platform/CrossThreadCopier.cpp:
+        (WebCore::::copy):
+        * platform/KURL.cpp:
+        (WebCore::KURL::copy):
+        * platform/network/HTTPHeaderMap.cpp:
+        (WebCore::HTTPHeaderMap::copyData):
+        * platform/network/ResourceErrorBase.cpp:
+        (WebCore::ResourceErrorBase::copy):
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::copyData):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::copyData):
+        * platform/sql/SQLValue.cpp:
+        (WebCore::SQLValue::SQLValue):
+        (WebCore::SQLValue::string):
+        * platform/sql/SQLValue.h:
+        (WebCore::SQLValue::SQLValue):
+        All constructors now initialize the m_number which is a double. Failure to
+        do so can result in unexpected crashes when it is copied in the copy constructor.
+        See http://blogs.msdn.com/oldnewthing/archive/2008/07/02/8679191.aspx, I was that colleague.
+        * platform/text/PlatformString.h:
+        * platform/text/String.cpp:
+        (WebCore::String::threadsafeCopy):
+        (WebCore::String::crossThreadString):
+        * platform/text/StringImpl.cpp:
+        Removed StringImpl::substringCopy which was no longer being used anywhere.
+        (WebCore::StringImpl::threadsafeCopy): Changed the name to indicate that
+        it is threadsafe.
+        (WebCore::StringImpl::crossThreadString): The way to get strings for
+        another thread which is not threadsafe. This shares the underlying buffer
+        with both strings and gives them a way to do threadsafe refcounting for it.
+        * platform/text/StringImpl.h:
+        * storage/ChangeVersionWrapper.cpp:
+        (WebCore::ChangeVersionWrapper::ChangeVersionWrapper):
+        * storage/Database.cpp:
+        (WebCore::updateGuidVersionMap):
+        (WebCore::Database::Database):
+        (WebCore::Database::getVersionFromDatabase):
+        (WebCore::Database::setVersionInDatabase):
+        (WebCore::Database::version):
+        (WebCore::Database::setExpectedVersion):
+        (WebCore::Database::securityOriginCopy):
+        (WebCore::Database::stringIdentifier):
+        * storage/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::scheduleNotifyDatabaseChanged):
+        * storage/OriginQuotaManager.cpp:
+        (WebCore::OriginQuotaManager::addDatabase):
+        * storage/SQLError.h:
+        (WebCore::SQLError::message):
+        (WebCore::SQLError::SQLError):
+        * storage/SQLStatement.cpp:
+        (WebCore::SQLStatement::SQLStatement):
+        * storage/StorageAreaSync.cpp:
+        (WebCore::StorageAreaSync::syncTimerFired):
+        * storage/StorageMap.cpp:
+        (WebCore::StorageMap::importItem):
+        * storage/StorageNamespaceImpl.cpp:
+        (WebCore::StorageNamespaceImpl::StorageNamespaceImpl):
+        * storage/StorageSyncManager.cpp:
+        (WebCore::StorageSyncManager::StorageSyncManager):
+        * workers/DefaultSharedWorkerRepository.cpp:
+        (WebCore::SharedWorkerProxy::url): Do the copy of the url in a way that is threadsafe.
+        (WebCore::SharedWorkerProxy::name):
+        (WebCore::SharedWorkerProxy::SharedWorkerProxy):
+        (WebCore::DefaultSharedWorkerRepository::getProxy): Do the copy of the url in a way that is threadsafe.
+        * workers/SharedWorkerThread.cpp:
+        (WebCore::SharedWorkerThread::SharedWorkerThread):
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::MessageWorkerContextTask::MessageWorkerContextTask):
+        (WebCore::MessageWorkerTask::MessageWorkerTask):
+        (WebCore::WorkerExceptionTask::WorkerExceptionTask):
+        * workers/WorkerRunLoop.cpp:
+        (WebCore::WorkerRunLoop::Task::Task):
+        (WebCore::WorkerRunLoop::postTaskForMode):
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
+
 2009-10-06  Girish Ramakrishnan  <girish at forwardbias.in>
 
         Reviewed by Simon Hausmann.
diff --git a/WebCore/dom/MessagePortChannel.cpp b/WebCore/dom/MessagePortChannel.cpp
index 34b2ce7..544cabd 100644
--- a/WebCore/dom/MessagePortChannel.cpp
+++ b/WebCore/dom/MessagePortChannel.cpp
@@ -39,7 +39,7 @@ PassOwnPtr<MessagePortChannel::EventData> MessagePortChannel::EventData::create(
 }
 
 MessagePortChannel::EventData::EventData(const String& message, PassOwnPtr<MessagePortChannelArray> channels)
-    : m_message(message.copy())
+    : m_message(message.crossThreadString())
     , m_channels(channels)
 {
 }
diff --git a/WebCore/loader/WorkerThreadableLoader.cpp b/WebCore/loader/WorkerThreadableLoader.cpp
index 6819759..bd362f4 100644
--- a/WebCore/loader/WorkerThreadableLoader.cpp
+++ b/WebCore/loader/WorkerThreadableLoader.cpp
@@ -91,7 +91,7 @@ WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<Threadable
                                                            const ResourceRequest& request, const ThreadableLoaderOptions& options)
     : m_workerClientWrapper(workerClientWrapper)
     , m_loaderProxy(loaderProxy)
-    , m_taskMode(taskMode.copy())
+    , m_taskMode(taskMode.crossThreadString())
 {
     ASSERT(m_workerClientWrapper.get());
     m_loaderProxy.postTaskToLoader(createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, this, request, options));
diff --git a/WebCore/loader/icon/IconDatabase.cpp b/WebCore/loader/icon/IconDatabase.cpp
index b78291d..78ca0a5 100644
--- a/WebCore/loader/icon/IconDatabase.cpp
+++ b/WebCore/loader/icon/IconDatabase.cpp
@@ -128,7 +128,7 @@ bool IconDatabase::open(const String& databasePath)
         return false;
     }
 
-    m_databaseDirectory = databasePath.copy();
+    m_databaseDirectory = databasePath.crossThreadString();
 
     // Formulate the full path for the database file
     m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, defaultDatabaseFilename());
@@ -227,7 +227,7 @@ Image* IconDatabase::iconForPageURL(const String& pageURLOriginal, const IntSize
     
     PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
     if (!pageRecord) {
-        pageURLCopy = pageURLOriginal.copy();
+        pageURLCopy = pageURLOriginal.crossThreadString();
         pageRecord = getOrCreatePageURLRecord(pageURLCopy);
     }
     
@@ -263,7 +263,7 @@ Image* IconDatabase::iconForPageURL(const String& pageURLOriginal, const IntSize
     // mark it to be read by the background thread
     if (iconRecord->imageDataStatus() == ImageDataStatusUnknown) {
         if (pageURLCopy.isNull())
-            pageURLCopy = pageURLOriginal.copy();
+            pageURLCopy = pageURLOriginal.crossThreadString();
     
         MutexLocker locker(m_pendingReadingLock);
         m_pageURLsInterestedInIcons.add(pageURLCopy);
@@ -312,7 +312,7 @@ String IconDatabase::iconURLForPageURL(const String& pageURLOriginal)
     
     PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal);
     if (!pageRecord)
-        pageRecord = getOrCreatePageURLRecord(pageURLOriginal.copy());
+        pageRecord = getOrCreatePageURLRecord(pageURLOriginal.crossThreadString());
     
     // If pageRecord is NULL, one of two things is true -
     // 1 - The initial url import is incomplete and this pageURL has already been marked to be notified once it is complete if an iconURL exists
@@ -321,7 +321,7 @@ String IconDatabase::iconURLForPageURL(const String& pageURLOriginal)
         return String();
     
     // Possible the pageRecord is around because it's a retained pageURL with no iconURL, so we have to check
-    return pageRecord->iconRecord() ? pageRecord->iconRecord()->iconURL().copy() : String();
+    return pageRecord->iconRecord() ? pageRecord->iconRecord()->iconURL().threadsafeCopy() : String();
 }
 
 #ifdef CAN_THEME_URL_ICON
@@ -405,7 +405,7 @@ void IconDatabase::retainIconForPageURL(const String& pageURLOriginal)
     String pageURL;
     
     if (!record) {
-        pageURL = pageURLOriginal.copy();
+        pageURL = pageURLOriginal.crossThreadString();
 
         record = new PageURLRecord(pageURL);
         m_pageURLToRecordMap.set(pageURL, record);
@@ -413,7 +413,7 @@ void IconDatabase::retainIconForPageURL(const String& pageURLOriginal)
     
     if (!record->retain()) {
         if (pageURL.isNull())
-            pageURL = pageURLOriginal.copy();
+            pageURL = pageURLOriginal.crossThreadString();
 
         // This page just had its retain count bumped from 0 to 1 - Record that fact
         m_retainedPageURLs.add(pageURL);
@@ -488,7 +488,7 @@ void IconDatabase::releaseIconForPageURL(const String& pageURLOriginal)
     // Mark stuff for deletion from the database only if we're not in private browsing
     if (!m_privateBrowsingEnabled) {
         MutexLocker locker(m_pendingSyncLock);
-        m_pageURLsPendingSync.set(pageURLOriginal.copy(), pageRecord->snapshot(true));
+        m_pageURLsPendingSync.set(pageURLOriginal.crossThreadString(), pageRecord->snapshot(true));
     
         // If this page is the last page to refer to a particular IconRecord, that IconRecord needs to
         // be marked for deletion
@@ -512,7 +512,7 @@ void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> dataOriginal,
         return;
     
     RefPtr<SharedBuffer> data = dataOriginal ? dataOriginal->copy() : 0;
-    String iconURL = iconURLOriginal.copy();
+    String iconURL = iconURLOriginal.crossThreadString();
     
     Vector<String> pageURLs;
     {
@@ -589,8 +589,8 @@ void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const Str
         if (pageRecord && pageRecord->iconRecord() && pageRecord->iconRecord()->iconURL() == iconURLOriginal)
             return;
             
-        pageURL = pageURLOriginal.copy();
-        iconURL = iconURLOriginal.copy();
+        pageURL = pageURLOriginal.crossThreadString();
+        iconURL = iconURLOriginal.crossThreadString();
 
         if (!pageRecord) {
             pageRecord = new PageURLRecord(pageURL);
@@ -847,13 +847,13 @@ bool IconDatabase::isOpen() const
 String IconDatabase::databasePath() const
 {
     MutexLocker locker(m_syncLock);
-    return m_completeDatabasePath.copy();
+    return m_completeDatabasePath.threadsafeCopy();
 }
 
 String IconDatabase::defaultDatabaseFilename()
 {
     DEFINE_STATIC_LOCAL(String, defaultDatabaseFilename, ("WebpageIcons.db"));
-    return defaultDatabaseFilename.copy();
+    return defaultDatabaseFilename.threadsafeCopy();
 }
 
 // Unlike getOrCreatePageURLRecord(), getOrCreateIconRecord() does not mark the icon as "interested in import"
diff --git a/WebCore/loader/icon/IconDatabaseNone.cpp b/WebCore/loader/icon/IconDatabaseNone.cpp
index 03a7964..7b7cc9f 100644
--- a/WebCore/loader/icon/IconDatabaseNone.cpp
+++ b/WebCore/loader/icon/IconDatabaseNone.cpp
@@ -53,7 +53,7 @@ const int updateTimerDelay = 5;
 String IconDatabase::defaultDatabaseFilename()
 {
     DEFINE_STATIC_LOCAL(String, defaultDatabaseFilename, ("Icons.db"));
-    return defaultDatabaseFilename.copy();
+    return defaultDatabaseFilename.threadsafeCopy();
 }
 
 IconDatabase* iconDatabase()
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index b91c1f1..5031895 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -116,9 +116,9 @@ SecurityOrigin::SecurityOrigin(const KURL& url)
 }
 
 SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
-    : m_protocol(other->m_protocol.copy())
-    , m_host(other->m_host.copy())
-    , m_domain(other->m_domain.copy())
+    : m_protocol(other->m_protocol.threadsafeCopy())
+    , m_host(other->m_host.threadsafeCopy())
+    , m_domain(other->m_domain.threadsafeCopy())
     , m_port(other->m_port)
     , m_noAccess(other->m_noAccess)
     , m_universalAccess(other->m_universalAccess)
@@ -144,7 +144,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty()
     return create(KURL());
 }
 
-PassRefPtr<SecurityOrigin> SecurityOrigin::copy()
+PassRefPtr<SecurityOrigin> SecurityOrigin::threadsafeCopy()
 {
     return adoptRef(new SecurityOrigin(this));
 }
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index 732afa8..57990d4 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -52,7 +52,7 @@ namespace WebCore {
 
         // Create a deep copy of this SecurityOrigin.  This method is useful
         // when marshalling a SecurityOrigin to another thread.
-        PassRefPtr<SecurityOrigin> copy();
+        PassRefPtr<SecurityOrigin> threadsafeCopy();
 
         // Set the domain property of this security origin to newDomain.  This
         // function does not check whether newDomain is a suffix of the current
diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp
index 9ca626f..d02da6c 100644
--- a/WebCore/platform/CrossThreadCopier.cpp
+++ b/WebCore/platform/CrossThreadCopier.cpp
@@ -41,7 +41,7 @@ namespace WebCore {
 
 CrossThreadCopierBase<false, String>::Type CrossThreadCopierBase<false, String>::copy(const String& str)
 {
-    return str.copy();
+    return str.crossThreadString();
 }
 
 CrossThreadCopierBase<false, ResourceError>::Type CrossThreadCopierBase<false, ResourceError>::copy(const ResourceError& error)
diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp
index aa9c624..ffacc19 100644
--- a/WebCore/platform/KURL.cpp
+++ b/WebCore/platform/KURL.cpp
@@ -529,7 +529,7 @@ void KURL::init(const KURL& base, const String& relative, const TextEncoding& en
 KURL KURL::copy() const
 {
     KURL result = *this;
-    result.m_string = result.m_string.copy();
+    result.m_string = result.m_string.crossThreadString();
     return result;
 }
 
diff --git a/WebCore/platform/network/HTTPHeaderMap.cpp b/WebCore/platform/network/HTTPHeaderMap.cpp
index ff470a0..07c66e8 100644
--- a/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -45,7 +45,7 @@ auto_ptr<CrossThreadHTTPHeaderMapData> HTTPHeaderMap::copyData() const
 
     HTTPHeaderMap::const_iterator end_it = end();
     for (HTTPHeaderMap::const_iterator it = begin(); it != end_it; ++it) {
-        data->append(make_pair(it->first.string().copy(), it->second.copy()));
+        data->append(make_pair(it->first.string().crossThreadString(), it->second.crossThreadString()));
     }
     return data;
 }
diff --git a/WebCore/platform/network/ResourceErrorBase.cpp b/WebCore/platform/network/ResourceErrorBase.cpp
index 370650f..97435ba 100644
--- a/WebCore/platform/network/ResourceErrorBase.cpp
+++ b/WebCore/platform/network/ResourceErrorBase.cpp
@@ -34,10 +34,10 @@ ResourceError ResourceErrorBase::copy() const
     lazyInit();
 
     ResourceError errorCopy;
-    errorCopy.m_domain = m_domain.copy();
+    errorCopy.m_domain = m_domain.crossThreadString();
     errorCopy.m_errorCode = m_errorCode;
-    errorCopy.m_failingURL = m_failingURL.copy();
-    errorCopy.m_localizedDescription = m_localizedDescription.copy();
+    errorCopy.m_failingURL = m_failingURL.crossThreadString();
+    errorCopy.m_localizedDescription = m_localizedDescription.crossThreadString();
     errorCopy.m_isNull = m_isNull;
     errorCopy.m_isCancellation = m_isCancellation;
     return errorCopy;
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index a651a3f..4c77999 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -73,13 +73,13 @@ auto_ptr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
     data->m_cachePolicy = cachePolicy();
     data->m_timeoutInterval = timeoutInterval();
     data->m_firstPartyForCookies = firstPartyForCookies().copy();
-    data->m_httpMethod = httpMethod().copy();
+    data->m_httpMethod = httpMethod().crossThreadString();
     data->m_httpHeaders.adopt(httpHeaderFields().copyData());
 
     data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
     size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
     for (size_t index = 0; index < encodingArraySize; ++index) {
-        data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].copy());
+        data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].crossThreadString());
     }
     if (m_httpBody)
         data->m_httpBody = m_httpBody->deepCopy();
diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp
index 7f8a4e2..fd44225 100644
--- a/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/WebCore/platform/network/ResourceResponseBase.cpp
@@ -108,12 +108,12 @@ auto_ptr<CrossThreadResourceResponseData> ResourceResponseBase::copyData() const
 {
     auto_ptr<CrossThreadResourceResponseData> data(new CrossThreadResourceResponseData());
     data->m_url = url().copy();
-    data->m_mimeType = mimeType().copy();
+    data->m_mimeType = mimeType().crossThreadString();
     data->m_expectedContentLength = expectedContentLength();
-    data->m_textEncodingName = textEncodingName().copy();
-    data->m_suggestedFilename = suggestedFilename().copy();
+    data->m_textEncodingName = textEncodingName().crossThreadString();
+    data->m_suggestedFilename = suggestedFilename().crossThreadString();
     data->m_httpStatusCode = httpStatusCode();
-    data->m_httpStatusText = httpStatusText().copy();
+    data->m_httpStatusText = httpStatusText().crossThreadString();
     data->m_httpHeaders.adopt(httpHeaderFields().copyData());
     data->m_lastModifiedDate = lastModifiedDate();
     return data;
diff --git a/WebCore/platform/sql/SQLValue.cpp b/WebCore/platform/sql/SQLValue.cpp
index 7e178f9..0ad643e 100644
--- a/WebCore/platform/sql/SQLValue.cpp
+++ b/WebCore/platform/sql/SQLValue.cpp
@@ -32,10 +32,10 @@
 namespace WebCore {
 
 SQLValue::SQLValue(const SQLValue& val)
+    : m_type(val.m_type)
+    , m_number(val.m_number)
+    , m_string(val.m_string.threadsafeCopy())
 {
-    m_number = val.m_number;
-    m_string = val.m_string.copy();
-    m_type = val.m_type;
 }
 
 String SQLValue::string() const
@@ -43,7 +43,7 @@ String SQLValue::string() const
     ASSERT(m_type == StringValue);
 
     // Must return a copy since ref-shared Strings are not thread safe
-    return m_string.copy();
+    return m_string.threadsafeCopy();
 }
 
 double SQLValue::number() const
diff --git a/WebCore/platform/sql/SQLValue.h b/WebCore/platform/sql/SQLValue.h
index 7d85051..0f854fc 100644
--- a/WebCore/platform/sql/SQLValue.h
+++ b/WebCore/platform/sql/SQLValue.h
@@ -38,9 +38,9 @@ namespace WebCore {
     public:
         enum Type { NullValue, NumberValue, StringValue };
 
-        SQLValue() : m_type(NullValue) { }
+        SQLValue() : m_type(NullValue), m_number(0.0) { }
         SQLValue(double number) : m_type(NumberValue), m_number(number) { }
-        SQLValue(const String& s) : m_type(StringValue), m_string(s) { }
+        SQLValue(const String& s) : m_type(StringValue), m_number(0.0), m_string(s) { }
         SQLValue(const SQLValue&);
 
         Type type() const { return m_type; }
diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h
index b9b4078..8d19c17 100644
--- a/WebCore/platform/text/PlatformString.h
+++ b/WebCore/platform/text/PlatformString.h
@@ -193,16 +193,13 @@ public:
 
     bool percentage(int& percentage) const;
 
-    // Makes a deep copy. Helpful only if you need to use a String on another thread.
+    // Returns a StringImpl suitable for use on another thread.
+    String crossThreadString() const;
+    // Makes a deep copy. Helpful only if you need to use a String on another thread
+    // (use crossThreadString if the method call doesn't need to be threadsafe).
     // Since the underlying StringImpl objects are immutable, there's no other reason
     // to ever prefer copy() over plain old assignment.
-    String copy() const;
-
-    // Makes a deep copy like copy() but only for a substring.
-    // (This ensures that you always get something suitable for a thread while subtring
-    // may not.  For example, in the empty string case, StringImpl::substring returns
-    // empty() which is not safe for another thread.)
-    String substringCopy(unsigned pos, unsigned len  = UINT_MAX) const;
+    String threadsafeCopy() const;
 
     bool isNull() const { return !m_impl; }
     bool isEmpty() const;
diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp
index e892ef6..bef2674 100644
--- a/WebCore/platform/text/String.cpp
+++ b/WebCore/platform/text/String.cpp
@@ -263,13 +263,6 @@ String String::substring(unsigned pos, unsigned len) const
     return m_impl->substring(pos, len);
 }
 
-String String::substringCopy(unsigned pos, unsigned len) const
-{
-    if (!m_impl) 
-        return String();
-    return m_impl->substringCopy(pos, len);
-}
-
 String String::lower() const
 {
     if (!m_impl)
@@ -590,11 +583,18 @@ float String::toFloat(bool* ok) const
     return m_impl->toFloat(ok);
 }
 
-String String::copy() const
+String String::threadsafeCopy() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->threadsafeCopy();
+}
+
+String String::crossThreadString() const
 {
     if (!m_impl)
         return String();
-    return m_impl->copy();
+    return m_impl->crossThreadString();
 }
 
 bool String::isEmpty() const
diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp
index 8b749c7..7d00370 100644
--- a/WebCore/platform/text/StringImpl.cpp
+++ b/WebCore/platform/text/StringImpl.cpp
@@ -218,15 +218,6 @@ PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length)
     return create(m_data + start, length);
 }
 
-PassRefPtr<StringImpl> StringImpl::substringCopy(unsigned start, unsigned length)
-{
-    start = min(start, m_length);
-    length = min(length, m_length - start);
-    if (!length)
-        return adoptRef(new StringImpl);
-    return create(m_data + start, length);
-}
-
 UChar32 StringImpl::characterStartingAt(unsigned i)
 {
     if (U16_IS_SINGLE(m_data[i]))
@@ -1074,12 +1065,25 @@ PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const Stri
     return adoptRef(new StringImpl(string, WithTerminatingNullCharacter()));
 }
 
-PassRefPtr<StringImpl> StringImpl::copy()
+PassRefPtr<StringImpl> StringImpl::threadsafeCopy() const
 {
     // Using the constructor directly to make sure that per-thread empty string instance isn't returned.
     return adoptRef(new StringImpl(m_data, m_length));
 }
 
+PassRefPtr<StringImpl> StringImpl::crossThreadString()
+{
+    SharedUChar* shared = sharedBuffer();
+    if (shared) {
+        RefPtr<StringImpl> impl = adoptRef(new StringImpl(const_cast<UChar*>(m_data), m_length, AdoptBuffer()));
+        impl->m_sharedBufferAndFlags.set(shared->crossThreadCopy().releaseRef());
+        return impl.release();
+    }
+
+    // Using the constructor directly to make sure that per-thread empty string instance isn't returned.
+    return adoptRef(new StringImpl(m_data, m_length));
+}
+
 StringImpl::SharedUChar* StringImpl::sharedBuffer()
 {
     if (m_length < minLengthToShare || m_bufferIsInternal)
diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h
index 8b4e82d..254f021 100644
--- a/WebCore/platform/text/StringImpl.h
+++ b/WebCore/platform/text/StringImpl.h
@@ -114,15 +114,12 @@ public:
     static unsigned computeHash(const UChar*, unsigned len);
     static unsigned computeHash(const char*);
     
-    // Makes a deep copy. Helpful only if you need to use a String on another thread.
+    // Returns a StringImpl suitable for use on another thread.
+    PassRefPtr<StringImpl> crossThreadString();
+    // Makes a deep copy. Helpful only if you need to use a String on another thread
+    // (use crossThreadString if the method call doesn't need to be threadsafe).
     // Since StringImpl objects are immutable, there's no other reason to make a copy.
-    PassRefPtr<StringImpl> copy();
-
-    // Makes a deep copy like copy() but only for a substring.
-    // (This ensures that you always get something suitable for a thread while subtring
-    // may not.  For example, in the empty string case, substring returns empty() which
-    // is not safe for another thread.)
-    PassRefPtr<StringImpl> substringCopy(unsigned pos, unsigned len  = UINT_MAX);
+    PassRefPtr<StringImpl> threadsafeCopy() const;
 
     PassRefPtr<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX);
 
diff --git a/WebCore/storage/ChangeVersionWrapper.cpp b/WebCore/storage/ChangeVersionWrapper.cpp
index 33660e7..17a9407 100644
--- a/WebCore/storage/ChangeVersionWrapper.cpp
+++ b/WebCore/storage/ChangeVersionWrapper.cpp
@@ -34,8 +34,8 @@
 namespace WebCore {
 
 ChangeVersionWrapper::ChangeVersionWrapper(const String& oldVersion, const String& newVersion)
-    : m_oldVersion(oldVersion.copy())
-    , m_newVersion(newVersion.copy())
+    : m_oldVersion(oldVersion.crossThreadString())
+    , m_newVersion(newVersion.crossThreadString())
 {
 }
 
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 1515eb3..9989bc0 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -102,7 +102,7 @@ static inline void updateGuidVersionMap(int guid, String newVersion)
     // FIXME: This is a quite-awkward restriction to have to program with.
 
     // Map null string to empty string (see comment above).
-    guidToVersionMap().set(guid, newVersion.isEmpty() ? String() : newVersion.copy());
+    guidToVersionMap().set(guid, newVersion.isEmpty() ? String() : newVersion.threadsafeCopy());
 }
 
 typedef HashMap<int, HashSet<Database*>*> GuidDatabaseMap;
@@ -150,7 +150,7 @@ PassRefPtr<Database> Database::openDatabase(Document* document, const String& na
 Database::Database(Document* document, const String& name, const String& expectedVersion)
     : m_transactionInProgress(false)
     , m_document(document)
-    , m_name(name.copy())
+    , m_name(name.crossThreadString())
     , m_guid(0)
     , m_expectedVersion(expectedVersion)
     , m_deleted(false)
@@ -247,7 +247,7 @@ bool Database::getVersionFromDatabase(String& version)
 
     m_databaseAuthorizer->disable();
 
-    bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, getVersionQuery.copy(), version);
+    bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, getVersionQuery.threadsafeCopy(), version);
     if (!result)
         LOG_ERROR("Failed to retrieve version from database %s", databaseDebugName().ascii().data());
 
@@ -285,7 +285,7 @@ bool Database::setVersionInDatabase(const String& version)
 
     m_databaseAuthorizer->disable();
 
-    bool result = setTextValueInDatabase(m_sqliteDatabase, setVersionQuery.copy(), version);
+    bool result = setTextValueInDatabase(m_sqliteDatabase, setVersionQuery.threadsafeCopy(), version);
     if (!result)
         LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), setVersionQuery.ascii().data());
 
@@ -618,7 +618,7 @@ String Database::version() const
     if (m_deleted)
         return String();
     MutexLocker locker(guidMutex());
-    return guidToVersionMap().get(m_guid).copy();
+    return guidToVersionMap().get(m_guid).threadsafeCopy();
 }
 
 void Database::deliverPendingCallback(void* context)
@@ -643,7 +643,7 @@ Vector<String> Database::tableNames()
 
 void Database::setExpectedVersion(const String& version)
 {
-    m_expectedVersion = version.copy();
+    m_expectedVersion = version.threadsafeCopy();
     // Update the in memory database version map.
     MutexLocker locker(guidMutex());
     updateGuidVersionMap(m_guid, version);
@@ -651,13 +651,13 @@ void Database::setExpectedVersion(const String& version)
 
 PassRefPtr<SecurityOrigin> Database::securityOriginCopy() const
 {
-    return m_securityOrigin->copy();
+    return m_securityOrigin->threadsafeCopy();
 }
 
 String Database::stringIdentifier() const
 {
     // Return a deep copy for ref counting thread safety
-    return m_name.copy();
+    return m_name.threadsafeCopy();
 }
 
 #endif
diff --git a/WebCore/storage/DatabaseTracker.cpp b/WebCore/storage/DatabaseTracker.cpp
index 491e6f1..265cd0d 100644
--- a/WebCore/storage/DatabaseTracker.cpp
+++ b/WebCore/storage/DatabaseTracker.cpp
@@ -762,7 +762,7 @@ void DatabaseTracker::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, cons
 {
     MutexLocker locker(notificationMutex());
 
-    notificationQueue().append(pair<SecurityOrigin*, String>(origin, name.copy()));
+    notificationQueue().append(pair<SecurityOrigin*, String>(origin, name.crossThreadString()));
     scheduleForNotification();
 }
 
diff --git a/WebCore/storage/OriginQuotaManager.cpp b/WebCore/storage/OriginQuotaManager.cpp
index b757f70..20bb34d 100644
--- a/WebCore/storage/OriginQuotaManager.cpp
+++ b/WebCore/storage/OriginQuotaManager.cpp
@@ -79,7 +79,7 @@ void OriginQuotaManager::addDatabase(SecurityOrigin* origin, const String& datab
     OriginUsageRecord* usageRecord = m_usageMap.get(origin);
     ASSERT(usageRecord);
 
-    usageRecord->addDatabase(databaseIdentifier.copy(), fullPath.copy());
+    usageRecord->addDatabase(databaseIdentifier.threadsafeCopy(), fullPath.threadsafeCopy());
 }
 
 void OriginQuotaManager::removeDatabase(SecurityOrigin* origin, const String& databaseIdentifier)
diff --git a/WebCore/storage/SQLError.h b/WebCore/storage/SQLError.h
index a17efa9..4414e6b 100644
--- a/WebCore/storage/SQLError.h
+++ b/WebCore/storage/SQLError.h
@@ -41,10 +41,10 @@ public:
     static PassRefPtr<SQLError> create(unsigned code, const String& message) { return adoptRef(new SQLError(code, message)); }
 
     unsigned code() const { return m_code; }
-    String message() const { return m_message.copy(); }
+    String message() const { return m_message.threadsafeCopy(); }
 
 private:
-    SQLError(unsigned code, const String& message) : m_code(code), m_message(message.copy()) { }
+    SQLError(unsigned code, const String& message) : m_code(code), m_message(message.threadsafeCopy()) { }
     unsigned m_code;
     String m_message;
 };
diff --git a/WebCore/storage/SQLStatement.cpp b/WebCore/storage/SQLStatement.cpp
index 970f757..b4eb9ef 100644
--- a/WebCore/storage/SQLStatement.cpp
+++ b/WebCore/storage/SQLStatement.cpp
@@ -50,7 +50,7 @@ PassRefPtr<SQLStatement> SQLStatement::create(const String& statement, const Vec
 }
 
 SQLStatement::SQLStatement(const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> errorCallback, bool readOnly)
-    : m_statement(statement.copy())
+    : m_statement(statement.crossThreadString())
     , m_arguments(arguments)
     , m_statementCallback(callback)
     , m_statementErrorCallback(errorCallback)
diff --git a/WebCore/storage/StorageAreaSync.cpp b/WebCore/storage/StorageAreaSync.cpp
index bec45aa..ad41e28 100644
--- a/WebCore/storage/StorageAreaSync.cpp
+++ b/WebCore/storage/StorageAreaSync.cpp
@@ -140,7 +140,7 @@ void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*)
         }
 
         for (; it != end; ++it)
-            m_itemsPendingSync.set(it->first.copy(), it->second.copy());
+            m_itemsPendingSync.set(it->first.crossThreadString(), it->second.crossThreadString());
 
         if (!m_syncScheduled) {
             m_syncScheduled = true;
diff --git a/WebCore/storage/StorageMap.cpp b/WebCore/storage/StorageMap.cpp
index ed91c8c..5498d9e 100644
--- a/WebCore/storage/StorageMap.cpp
+++ b/WebCore/storage/StorageMap.cpp
@@ -162,10 +162,10 @@ void StorageMap::importItem(const String& key, const String& value)
 {
     // Be sure to copy the keys/values as items imported on a background thread are destined
     // to cross a thread boundary
-    pair<HashMap<String, String>::iterator, bool> result = m_map.add(key.copy(), String());
+    pair<HashMap<String, String>::iterator, bool> result = m_map.add(key.threadsafeCopy(), String());
 
     if (result.second)
-        result.first->second = value.copy();
+        result.first->second = value.threadsafeCopy();
 
     // Update quota.
     ASSERT(m_currentLength + value.length() >= m_currentLength);
diff --git a/WebCore/storage/StorageNamespaceImpl.cpp b/WebCore/storage/StorageNamespaceImpl.cpp
index bc9d90c..19ff6b4 100644
--- a/WebCore/storage/StorageNamespaceImpl.cpp
+++ b/WebCore/storage/StorageNamespaceImpl.cpp
@@ -65,7 +65,7 @@ PassRefPtr<StorageNamespace> StorageNamespaceImpl::sessionStorageNamespace()
 
 StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path, unsigned quota)
     : m_storageType(storageType)
-    , m_path(path.copy())  // Copy makes it safe for our other thread to access the path.
+    , m_path(path.crossThreadString())
     , m_syncManager(0)
     , m_quota(quota)
     , m_isShutdown(false)
diff --git a/WebCore/storage/StorageSyncManager.cpp b/WebCore/storage/StorageSyncManager.cpp
index 416b81c..f9276dd 100644
--- a/WebCore/storage/StorageSyncManager.cpp
+++ b/WebCore/storage/StorageSyncManager.cpp
@@ -48,7 +48,7 @@ PassRefPtr<StorageSyncManager> StorageSyncManager::create(const String& path)
 }
 
 StorageSyncManager::StorageSyncManager(const String& path)
-    : m_path(path.copy())
+    : m_path(path.crossThreadString())
 {
     ASSERT(isMainThread());
     ASSERT(!m_path.isEmpty());
diff --git a/WebCore/workers/DefaultSharedWorkerRepository.cpp b/WebCore/workers/DefaultSharedWorkerRepository.cpp
index 2126df4..8b1a480 100644
--- a/WebCore/workers/DefaultSharedWorkerRepository.cpp
+++ b/WebCore/workers/DefaultSharedWorkerRepository.cpp
@@ -63,8 +63,13 @@ public:
     void setThread(PassRefPtr<SharedWorkerThread> thread) { m_thread = thread; }
     SharedWorkerThread* thread() { return m_thread.get(); }
     bool isClosing() const { return m_closing; }
-    KURL url() const { return m_url.copy(); }
-    String name() const { return m_name.copy(); }
+    KURL url() const
+    {
+        // Don't use m_url.copy() because it isn't a threadsafe method.
+        return KURL(ParsedURLString, m_url.string().threadsafeCopy());
+    }
+
+    String name() const { return m_name.threadsafeCopy(); }
     bool matches(const String& name, PassRefPtr<SecurityOrigin> origin, const KURL& urlToMatch) const;
 
     // WorkerLoaderProxy
@@ -102,7 +107,7 @@ private:
 
 SharedWorkerProxy::SharedWorkerProxy(const String& name, const KURL& url, PassRefPtr<SecurityOrigin> origin)
     : m_closing(false)
-    , m_name(name.copy())
+    , m_name(name.crossThreadString())
     , m_url(url.copy())
     , m_origin(origin)
 {
@@ -385,8 +390,9 @@ void DefaultSharedWorkerRepository::connectToWorker(PassRefPtr<SharedWorker> wor
 PassRefPtr<SharedWorkerProxy> DefaultSharedWorkerRepository::getProxy(const String& name, const KURL& url)
 {
     // Look for an existing worker, and create one if it doesn't exist.
-    // Items in the cache are freed on another thread, so copy the URL before creating the origin, to make sure no references to external strings linger.
-    RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url.copy());
+    // Items in the cache are freed on another thread, so do a threadsafe copy of the URL before creating the origin,
+    // to make sure no references to external strings linger.
+    RefPtr<SecurityOrigin> origin = SecurityOrigin::create(KURL(ParsedURLString, url.string().threadsafeCopy()));
     for (unsigned i = 0; i < m_proxies.size(); i++) {
         if (!m_proxies[i]->isClosing() && m_proxies[i]->matches(name, origin, url))
             return m_proxies[i];
diff --git a/WebCore/workers/SharedWorkerThread.cpp b/WebCore/workers/SharedWorkerThread.cpp
index ded4834..e59df4f 100644
--- a/WebCore/workers/SharedWorkerThread.cpp
+++ b/WebCore/workers/SharedWorkerThread.cpp
@@ -45,7 +45,7 @@ PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, co
 
 SharedWorkerThread::SharedWorkerThread(const String& name, const KURL& url, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy)
     : WorkerThread(url, userAgent, sourceCode, workerLoaderProxy, workerReportingProxy)
-    , m_name(name.copy())
+    , m_name(name.crossThreadString())
 {
 }
 
diff --git a/WebCore/workers/WorkerMessagingProxy.cpp b/WebCore/workers/WorkerMessagingProxy.cpp
index 3d28f9e..381bc4a 100644
--- a/WebCore/workers/WorkerMessagingProxy.cpp
+++ b/WebCore/workers/WorkerMessagingProxy.cpp
@@ -53,7 +53,7 @@ public:
 
 private:
     MessageWorkerContextTask(const String& message, PassOwnPtr<MessagePortChannelArray> channels)
-        : m_message(message.copy())
+        : m_message(message.crossThreadString())
         , m_channels(channels)
     {
     }
@@ -81,7 +81,7 @@ public:
 
 private:
     MessageWorkerTask(const String& message, PassOwnPtr<MessagePortChannelArray> channels, WorkerMessagingProxy* messagingProxy)
-        : m_message(message.copy())
+        : m_message(message.crossThreadString())
         , m_channels(channels)
         , m_messagingProxy(messagingProxy)
     {
@@ -112,9 +112,9 @@ public:
 
 private:
     WorkerExceptionTask(const String& errorMessage, int lineNumber, const String& sourceURL, WorkerMessagingProxy* messagingProxy)
-        : m_errorMessage(errorMessage.copy())
+        : m_errorMessage(errorMessage.crossThreadString())
         , m_lineNumber(lineNumber)
-        , m_sourceURL(sourceURL.copy())
+        , m_sourceURL(sourceURL.crossThreadString())
         , m_messagingProxy(messagingProxy)
     {
     }
diff --git a/WebCore/workers/WorkerRunLoop.cpp b/WebCore/workers/WorkerRunLoop.cpp
index 52d650f..39b21c6 100644
--- a/WebCore/workers/WorkerRunLoop.cpp
+++ b/WebCore/workers/WorkerRunLoop.cpp
@@ -77,7 +77,7 @@ public:
 private:
     Task(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
         : m_task(task)
-        , m_mode(mode.copy())
+        , m_mode(mode.crossThreadString())
     {
     }
 
@@ -205,7 +205,7 @@ void WorkerRunLoop::postTask(PassRefPtr<ScriptExecutionContext::Task> task)
 
 void WorkerRunLoop::postTaskForMode(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
 {
-    m_messageQueue.append(Task::create(task, mode.copy()));
+    m_messageQueue.append(Task::create(task, mode.crossThreadString()));
 }
 
 } // namespace WebCore
diff --git a/WebCore/workers/WorkerThread.cpp b/WebCore/workers/WorkerThread.cpp
index 22253bf..467157b 100644
--- a/WebCore/workers/WorkerThread.cpp
+++ b/WebCore/workers/WorkerThread.cpp
@@ -71,8 +71,8 @@ private:
 
 WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
     : m_scriptURL(scriptURL.copy())
-    , m_userAgent(userAgent.copy())
-    , m_sourceCode(sourceCode.copy())
+    , m_userAgent(userAgent.crossThreadString())
+    , m_sourceCode(sourceCode.crossThreadString())
 {
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list