Commit cbcba73f authored by cmumford@chromium.org's avatar cmumford@chromium.org

IndexedDB: Fixed threading bugs with use of AtomicStrings.

    
Some IndexedDB classes (IDBCursor, IDBRequest, IDBTransaction, and
IDBVersionChangeEvent) were using static local AtomicStrings on different
threads. This is safe, as long as these static strings are properly
created - which they were not. Switching to an initialization mechanism
which mirrors the Core static strings fixes this.

BUG=393728

Review URL: https://codereview.chromium.org/426063010

git-svn-id: svn://svn.chromium.org/blink/trunk@180205 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3b275d84
......@@ -84,10 +84,29 @@ source_set("modules_testing") {
]
}
# GYP version: WebKit/Source/modules/modules.gyp:make_modules_generated
action("module_names") {
script = "../build/scripts/make_names.py"
module_names_in = "indexeddb/IndexedDBNames.in"
inputs = make_names_files + [ module_names_in ]
outputs = [
"$blink_modules_output_dir/IndexedDBNames.cpp",
"$blink_modules_output_dir/IndexedDBNames.h",
]
args = [
rebase_path(module_names_in, root_build_dir),
"--output_dir",
rebase_path(blink_modules_output_dir, root_build_dir),
]
}
# GYP version: WebKit/Source/modules/modules_generated.gyp:make_modules_generated
group("make_modules_generated") {
deps = [
"//third_party/WebKit/Source/core:core_event_interfaces",
"//third_party/WebKit/Source/bindings/modules:bindings_modules_generated",
":module_names",
]
}
......@@ -11,6 +11,7 @@
#include "modules/EventModulesFactory.h"
#include "modules/EventModulesNames.h"
#include "modules/EventTargetModulesNames.h"
#include "modules/IndexedDBNames.h"
namespace blink {
......@@ -23,6 +24,7 @@ void ModulesInitializer::init()
EventTargetNames::initModules();
Document::registerEventFactory(EventModulesFactory::create());
ModuleBindingsInitializer::init();
IndexedDBNames::init();
CoreInitializer::init();
......
......@@ -32,6 +32,7 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/inspector/ScriptCallStack.h"
#include "modules/IndexedDBNames.h"
#include "modules/indexeddb/IDBAny.h"
#include "modules/indexeddb/IDBDatabase.h"
#include "modules/indexeddb/IDBObjectStore.h"
......@@ -53,30 +54,6 @@ IDBCursor* IDBCursor::create(PassOwnPtr<blink::WebIDBCursor> backend, blink::Web
return new IDBCursor(backend, direction, request, source, transaction);
}
const AtomicString& IDBCursor::directionNext()
{
DEFINE_STATIC_LOCAL(AtomicString, next, ("next", AtomicString::ConstructFromLiteral));
return next;
}
const AtomicString& IDBCursor::directionNextUnique()
{
DEFINE_STATIC_LOCAL(AtomicString, nextunique, ("nextunique", AtomicString::ConstructFromLiteral));
return nextunique;
}
const AtomicString& IDBCursor::directionPrev()
{
DEFINE_STATIC_LOCAL(AtomicString, prev, ("prev", AtomicString::ConstructFromLiteral));
return prev;
}
const AtomicString& IDBCursor::directionPrevUnique()
{
DEFINE_STATIC_LOCAL(AtomicString, prevunique, ("prevunique", AtomicString::ConstructFromLiteral));
return prevunique;
}
IDBCursor::IDBCursor(PassOwnPtr<blink::WebIDBCursor> backend, blink::WebIDBCursorDirection direction, IDBRequest* request, IDBAny* source, IDBTransaction* transaction)
: m_backend(backend)
, m_request(request)
......@@ -382,37 +359,37 @@ void IDBCursor::handleBlobAcks()
blink::WebIDBCursorDirection IDBCursor::stringToDirection(const String& directionString, ExceptionState& exceptionState)
{
if (directionString == IDBCursor::directionNext())
if (directionString == IndexedDBNames::next)
return blink::WebIDBCursorDirectionNext;
if (directionString == IDBCursor::directionNextUnique())
if (directionString == IndexedDBNames::nextunique)
return blink::WebIDBCursorDirectionNextNoDuplicate;
if (directionString == IDBCursor::directionPrev())
if (directionString == IndexedDBNames::prev)
return blink::WebIDBCursorDirectionPrev;
if (directionString == IDBCursor::directionPrevUnique())
if (directionString == IndexedDBNames::prevunique)
return blink::WebIDBCursorDirectionPrevNoDuplicate;
exceptionState.throwTypeError("The direction provided ('" + directionString + "') is not one of 'next', 'nextunique', 'prev', or 'prevunique'.");
return blink::WebIDBCursorDirectionNext;
}
const AtomicString& IDBCursor::directionToString(unsigned short direction)
const String& IDBCursor::direction() const
{
switch (direction) {
switch (m_direction) {
case blink::WebIDBCursorDirectionNext:
return IDBCursor::directionNext();
return IndexedDBNames::next;
case blink::WebIDBCursorDirectionNextNoDuplicate:
return IDBCursor::directionNextUnique();
return IndexedDBNames::nextunique;
case blink::WebIDBCursorDirectionPrev:
return IDBCursor::directionPrev();
return IndexedDBNames::prev;
case blink::WebIDBCursorDirectionPrevNoDuplicate:
return IDBCursor::directionPrevUnique();
return IndexedDBNames::prevunique;
default:
ASSERT_NOT_REACHED();
return IDBCursor::directionNext();
return IndexedDBNames::next;
}
}
......
......@@ -47,13 +47,7 @@ class WebBlobInfo;
class IDBCursor : public GarbageCollectedFinalized<IDBCursor>, public ScriptWrappable {
public:
static const AtomicString& directionNext();
static const AtomicString& directionNextUnique();
static const AtomicString& directionPrev();
static const AtomicString& directionPrevUnique();
static WebIDBCursorDirection stringToDirection(const String& modeString, ExceptionState&);
static const AtomicString& directionToString(unsigned short mode);
static IDBCursor* create(PassOwnPtr<WebIDBCursor>, WebIDBCursorDirection, IDBRequest*, IDBAny* source, IDBTransaction*);
virtual ~IDBCursor();
......@@ -61,7 +55,7 @@ public:
void contextWillBeDestroyed() { m_backend.clear(); }
// Implement the IDL
const String& direction() const { return directionToString(m_direction); }
const String& direction() const;
ScriptValue key(ScriptState*);
ScriptValue primaryKey(ScriptState*);
ScriptValue value(ScriptState*);
......
......@@ -34,6 +34,7 @@
#include "bindings/modules/v8/IDBBindingUtilities.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/EventQueue.h"
#include "modules/IndexedDBNames.h"
#include "modules/indexeddb/IDBCursorWithValue.h"
#include "modules/indexeddb/IDBDatabase.h"
#include "modules/indexeddb/IDBEventDispatcher.h"
......@@ -129,13 +130,11 @@ ScriptValue IDBRequest::source() const
const String& IDBRequest::readyState() const
{
ASSERT(m_readyState == PENDING || m_readyState == DONE);
DEFINE_STATIC_LOCAL(AtomicString, pending, ("pending", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, done, ("done", AtomicString::ConstructFromLiteral));
if (m_readyState == PENDING)
return pending;
return IndexedDBNames::pending;
return done;
return IndexedDBNames::done;
}
void IDBRequest::abort()
......
......@@ -31,6 +31,7 @@
#include "core/dom/ExecutionContext.h"
#include "core/events/EventQueue.h"
#include "core/inspector/ScriptCallStack.h"
#include "modules/IndexedDBNames.h"
#include "modules/indexeddb/IDBDatabase.h"
#include "modules/indexeddb/IDBEventDispatcher.h"
#include "modules/indexeddb/IDBIndex.h"
......@@ -58,24 +59,6 @@ IDBTransaction* IDBTransaction::create(ExecutionContext* context, int64_t id, ID
return transaction;
}
const AtomicString& IDBTransaction::modeReadOnly()
{
DEFINE_STATIC_LOCAL(AtomicString, readonly, ("readonly", AtomicString::ConstructFromLiteral));
return readonly;
}
const AtomicString& IDBTransaction::modeReadWrite()
{
DEFINE_STATIC_LOCAL(AtomicString, readwrite, ("readwrite", AtomicString::ConstructFromLiteral));
return readwrite;
}
const AtomicString& IDBTransaction::modeVersionChange()
{
DEFINE_STATIC_LOCAL(AtomicString, versionchange, ("versionchange", AtomicString::ConstructFromLiteral));
return versionchange;
}
IDBTransaction::IDBTransaction(ExecutionContext* context, int64_t id, const Vector<String>& objectStoreNames, blink::WebIDBTransactionMode mode, IDBDatabase* db, IDBOpenDBRequest* openDBRequest, const IDBDatabaseMetadata& previousMetadata)
: ActiveDOMObject(context)
, m_id(id)
......@@ -117,11 +100,6 @@ void IDBTransaction::trace(Visitor* visitor)
EventTargetWithInlineData::trace(visitor);
}
const String& IDBTransaction::mode() const
{
return modeToString(m_mode);
}
void IDBTransaction::setError(PassRefPtrWillBeRawPtr<DOMError> error)
{
ASSERT(m_state != Finished);
......@@ -301,33 +279,30 @@ bool IDBTransaction::hasPendingActivity() const
blink::WebIDBTransactionMode IDBTransaction::stringToMode(const String& modeString, ExceptionState& exceptionState)
{
if (modeString == IDBTransaction::modeReadOnly())
if (modeString == IndexedDBNames::readonly)
return blink::WebIDBTransactionModeReadOnly;
if (modeString == IDBTransaction::modeReadWrite())
if (modeString == IndexedDBNames::readwrite)
return blink::WebIDBTransactionModeReadWrite;
exceptionState.throwTypeError("The mode provided ('" + modeString + "') is not one of 'readonly' or 'readwrite'.");
return blink::WebIDBTransactionModeReadOnly;
}
const AtomicString& IDBTransaction::modeToString(blink::WebIDBTransactionMode mode)
const String& IDBTransaction::mode() const
{
switch (mode) {
switch (m_mode) {
case blink::WebIDBTransactionModeReadOnly:
return IDBTransaction::modeReadOnly();
break;
return IndexedDBNames::readonly;
case blink::WebIDBTransactionModeReadWrite:
return IDBTransaction::modeReadWrite();
break;
return IndexedDBNames::readwrite;
case blink::WebIDBTransactionModeVersionChange:
return IDBTransaction::modeVersionChange();
break;
return IndexedDBNames::versionchange;
}
ASSERT_NOT_REACHED();
return IDBTransaction::modeReadOnly();
return IndexedDBNames::readonly;
}
const AtomicString& IDBTransaction::interfaceName() const
......
......@@ -60,12 +60,7 @@ public:
virtual ~IDBTransaction();
virtual void trace(Visitor*) OVERRIDE;
static const AtomicString& modeReadOnly();
static const AtomicString& modeReadWrite();
static const AtomicString& modeVersionChange();
static WebIDBTransactionMode stringToMode(const String&, ExceptionState&);
static const AtomicString& modeToString(WebIDBTransactionMode);
// When the connection is closed backend will be 0.
WebIDBDatabase* backendDB() const;
......
......@@ -26,6 +26,8 @@
#include "config.h"
#include "modules/indexeddb/IDBVersionChangeEvent.h"
#include "modules/IndexedDBNames.h"
namespace blink {
......@@ -71,11 +73,9 @@ unsigned long long IDBVersionChangeEvent::newVersion(bool& isNull) const
const AtomicString& IDBVersionChangeEvent::dataLoss() const
{
DEFINE_STATIC_LOCAL(AtomicString, total, ("total", AtomicString::ConstructFromLiteral));
if (m_dataLoss == blink::WebIDBDataLossTotal)
return total;
DEFINE_STATIC_LOCAL(AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
return none;
return IndexedDBNames::total;
return IndexedDBNames::none;
}
const AtomicString& IDBVersionChangeEvent::interfaceName() const
......
namespace="IndexedDB"
# http://www.w3.org/TR/IndexedDB/#idl-def-IDBCursorDirection
next
nextunique
prev
prevunique
# http://www.w3.org/TR/IndexedDB/#idl-def-IDBTransactionMode
readonly
readwrite
versionchange
# http://www.w3.org/TR/IndexedDB/#idl-def-IDBRequestReadyState
pending
done
# http://www.w3.org/TR/IndexedDB/#idl-def-IDBVersionChangeEvent
# FIXME: This enum is non-standard, see
# https://www.w3.org/Bugs/Public/show_bug.cgi?id=22370
none
total
......@@ -42,6 +42,7 @@
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorState.h"
#include "core/page/Page.h"
#include "modules/IndexedDBNames.h"
#include "modules/indexeddb/DOMWindowIndexedDatabase.h"
#include "modules/indexeddb/IDBCursor.h"
#include "modules/indexeddb/IDBCursorWithValue.h"
......@@ -200,7 +201,7 @@ void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, cons
idbOpenDBRequest->addEventListener(EventTypeNames::success, callback, false);
}
static IDBTransaction* transactionForDatabase(ExecutionContext* executionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly())
static IDBTransaction* transactionForDatabase(ExecutionContext* executionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IndexedDBNames::readonly)
{
TrackExceptionState exceptionState;
IDBTransaction* idbTransaction = idbDatabase->transaction(executionContext, objectStoreName, mode, exceptionState);
......@@ -730,7 +731,7 @@ public:
{
if (!requestCallback()->isActive())
return;
IDBTransaction* idbTransaction = transactionForDatabase(context(), idbDatabase, m_objectStoreName, IDBTransaction::modeReadWrite());
IDBTransaction* idbTransaction = transactionForDatabase(context(), idbDatabase, m_objectStoreName, IndexedDBNames::readwrite);
if (!idbTransaction) {
m_requestCallback->sendFailure("Could not get transaction");
return;
......
......@@ -43,7 +43,7 @@
'<(DEPTH)/third_party/sqlite/sqlite.gyp:sqlite',
'../config.gyp:config',
'../core/core.gyp:webcore',
'make_modules_generated',
'modules_generated.gyp:make_modules_generated',
],
'defines': [
'BLINK_IMPLEMENTATION=1',
......@@ -127,25 +127,5 @@
'<@(modules_testing_files)',
],
},
{
# FIXME: should be in modules_generated.gyp
# GN version: //third_party/WebKit/Source/modules:make_modules_generated
'target_name': 'make_modules_generated',
'type': 'none',
'hard_dependency': 1,
'dependencies': [
#'generated_testing_idls',
'../core/core_generated.gyp:core_event_interfaces',
'../bindings/modules/generated.gyp:modules_event_generated',
'../config.gyp:config',
],
'sources': [
# bison rule
'../core/css/CSSGrammar.y',
'../core/xml/XPathGrammar.y',
],
'actions': [
],
}],
}
......@@ -287,6 +287,8 @@
'<(blink_modules_output_dir)/EventTargetModulesInterfaces.h',
'<(blink_modules_output_dir)/EventTargetModulesNames.cpp',
'<(blink_modules_output_dir)/EventTargetModulesNames.h',
'<(blink_modules_output_dir)/IndexedDBNames.cpp',
'<(blink_modules_output_dir)/IndexedDBNames.h',
],
'modules_files': [
'<@(extra_blink_module_files)',
......
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'includes': [
'modules_generated.gypi',
'../bindings/scripts/scripts.gypi',
'../build/features.gypi',
'../build/scripts/scripts.gypi',
],
'targets': [
{
# GN version: //third_party/WebKit/Source/modules:make_modules_generated
'target_name': 'make_modules_generated',
'type': 'none',
'hard_dependency': 1,
'dependencies': [
'../bindings/modules/generated.gyp:modules_event_generated',
'../config.gyp:config',
],
'actions': [
{
'action_name': 'IndexedDBNames',
'inputs': [
'<@(make_names_files)',
'indexeddb/IndexedDBNames.in',
],
'outputs': [
'<(blink_modules_output_dir)/IndexedDBNames.cpp',
'<(blink_modules_output_dir)/IndexedDBNames.h',
],
'action': [
'python',
'../build/scripts/make_names.py',
'indexeddb/IndexedDBNames.in',
'--output_dir',
'<(blink_modules_output_dir)',
],
},
],
},
],
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment