https://bugs.webkit.org/show_bug.cgi?id=153724
Reviewed by Alex Christensen.
No new tests (All existing tests pass without flakiness).
IDBCursors did not properly keep their JS wrappers alive.
Making them ActiveDOMObjects that keep track of how many requests might be in flight fixes this.
This also makes them actually keep their opening-request live via the opaque-root mechanism.
IDBCursorWithValue also needed to opt in to all of these mechanisms.
* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* Modules/indexeddb/IDBCursor.h:
(WebCore::IDBCursor::hasPendingActivity): The base IDBCursor always has no pending activity,
to maintain current behavior in LegacyIDB. This weirdness will go away when LegacyIDB does.
* Modules/indexeddb/IDBCursor.idl:
* Modules/indexeddb/IDBCursorWithValue.idl:
Track a count for all outstanding requests to keep the cursor alive as an ActiveDOMObject.
* Modules/indexeddb/client/IDBCursorImpl.cpp:
(WebCore::IDBClient::IDBCursor::IDBCursor):
(WebCore::IDBClient::IDBCursor::update):
(WebCore::IDBClient::IDBCursor::uncheckedIterateCursor):
(WebCore::IDBClient::IDBCursor::deleteFunction):
(WebCore::IDBClient::IDBCursor::activeDOMObjectName):
(WebCore::IDBClient::IDBCursor::canSuspendForDocumentSuspension):
(WebCore::IDBClient::IDBCursor::hasPendingActivity):
(WebCore::IDBClient::IDBCursor::decrementOutstandingRequestCount):
* Modules/indexeddb/client/IDBCursorImpl.h:
Rework the "delete" family of functions on the object store to allow for returning a modern IDBRequest.
A lot of this can go away when LegacyIDB does.
* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::deleteFunction):
(WebCore::IDBClient::IDBObjectStore::doDelete):
(WebCore::IDBClient::IDBObjectStore::modernDelete):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:
* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::setSource): Setup a ScopeGuard to decrement the cursor's request
count whenever it makes sense to do so.
(WebCore::IDBClient::IDBRequest::dispatchEvent): Clear the ScopeGuard (if it exists) to decrement the count.
(WebCore::IDBClient::IDBRequest::willIterateCursor): Set the ScopeGuard.
(WebCore::IDBClient::IDBRequest::didOpenOrIterateCursor): Clear the ScopeGuard (if it exists) to decrement the count.
* Modules/indexeddb/client/IDBRequestImpl.h:
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::ScopeGuard::ScopeGuard): Deleted.
(WebCore::IDBServer::ScopeGuard::~ScopeGuard): Deleted.
(WebCore::IDBServer::ScopeGuard::enable): Deleted.
(WebCore::IDBServer::ScopeGuard::disable): Deleted.
* bindings/js/JSIDBCursorWithValueCustom.cpp: Added.
(WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
* platform/ScopeGuard.h: Added.
(WebCore::ScopeGuard::ScopeGuard):
(WebCore::ScopeGuard::~ScopeGuard):
(WebCore::ScopeGuard::enable):
(WebCore::ScopeGuard::disable):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195997
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
bindings/js/JSHistoryCustom.cpp
bindings/js/JSIDBAnyCustom.cpp
bindings/js/JSIDBCursorCustom.cpp
+ bindings/js/JSIDBCursorWithValueCustom.cpp
bindings/js/JSIDBDatabaseCustom.cpp
bindings/js/JSIDBObjectStoreCustom.cpp
bindings/js/JSImageConstructor.cpp
+2016-02-01 Brady Eidson <beidson@apple.com>
+
+ Modern IDB: Cursors (still) do not keep their opening request alive.
+ https://bugs.webkit.org/show_bug.cgi?id=153724
+
+ Reviewed by Alex Christensen.
+
+ No new tests (All existing tests pass without flakiness).
+
+ IDBCursors did not properly keep their JS wrappers alive.
+ Making them ActiveDOMObjects that keep track of how many requests might be in flight fixes this.
+ This also makes them actually keep their opening-request live via the opaque-root mechanism.
+
+ IDBCursorWithValue also needed to opt in to all of these mechanisms.
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+
+ * Modules/indexeddb/IDBCursor.h:
+ (WebCore::IDBCursor::hasPendingActivity): The base IDBCursor always has no pending activity,
+ to maintain current behavior in LegacyIDB. This weirdness will go away when LegacyIDB does.
+ * Modules/indexeddb/IDBCursor.idl:
+ * Modules/indexeddb/IDBCursorWithValue.idl:
+
+ Track a count for all outstanding requests to keep the cursor alive as an ActiveDOMObject.
+ * Modules/indexeddb/client/IDBCursorImpl.cpp:
+ (WebCore::IDBClient::IDBCursor::IDBCursor):
+ (WebCore::IDBClient::IDBCursor::update):
+ (WebCore::IDBClient::IDBCursor::uncheckedIterateCursor):
+ (WebCore::IDBClient::IDBCursor::deleteFunction):
+ (WebCore::IDBClient::IDBCursor::activeDOMObjectName):
+ (WebCore::IDBClient::IDBCursor::canSuspendForDocumentSuspension):
+ (WebCore::IDBClient::IDBCursor::hasPendingActivity):
+ (WebCore::IDBClient::IDBCursor::decrementOutstandingRequestCount):
+ * Modules/indexeddb/client/IDBCursorImpl.h:
+
+ Rework the "delete" family of functions on the object store to allow for returning a modern IDBRequest.
+ A lot of this can go away when LegacyIDB does.
+ * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+ (WebCore::IDBClient::IDBObjectStore::deleteFunction):
+ (WebCore::IDBClient::IDBObjectStore::doDelete):
+ (WebCore::IDBClient::IDBObjectStore::modernDelete):
+ * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+
+ * Modules/indexeddb/client/IDBRequestImpl.cpp:
+ (WebCore::IDBClient::IDBRequest::setSource): Setup a ScopeGuard to decrement the cursor's request
+ count whenever it makes sense to do so.
+ (WebCore::IDBClient::IDBRequest::dispatchEvent): Clear the ScopeGuard (if it exists) to decrement the count.
+ (WebCore::IDBClient::IDBRequest::willIterateCursor): Set the ScopeGuard.
+ (WebCore::IDBClient::IDBRequest::didOpenOrIterateCursor): Clear the ScopeGuard (if it exists) to decrement the count.
+ * Modules/indexeddb/client/IDBRequestImpl.h:
+
+ * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+ (WebCore::IDBServer::ScopeGuard::ScopeGuard): Deleted.
+ (WebCore::IDBServer::ScopeGuard::~ScopeGuard): Deleted.
+ (WebCore::IDBServer::ScopeGuard::enable): Deleted.
+ (WebCore::IDBServer::ScopeGuard::disable): Deleted.
+
+ * bindings/js/JSIDBCursorWithValueCustom.cpp: Added.
+ (WebCore::JSIDBCursorWithValue::visitAdditionalChildren):
+
+ * platform/ScopeGuard.h: Added.
+ (WebCore::ScopeGuard::ScopeGuard):
+ (WebCore::ScopeGuard::~ScopeGuard):
+ (WebCore::ScopeGuard::enable):
+ (WebCore::ScopeGuard::disable):
+
2016-02-01 Sun-woo Nam <sunny.nam@samsung.com>
Free Colormap when XWindow is destroyed.
virtual bool isModernCursor() const { return false; }
+ virtual bool hasPendingActivity() const { return false; }
+
protected:
IDBCursor();
};
[
Conditional=INDEXED_DATABASE,
EnabledAtRuntime=IndexedDB,
+ ActiveDOMObject,
SkipVTableValidation,
JSCustomMarkFunction,
] interface IDBCursor {
[
Conditional=INDEXED_DATABASE,
EnabledAtRuntime=IndexedDB,
+ ActiveDOMObject,
SkipVTableValidation,
+ JSCustomMarkFunction,
] interface IDBCursorWithValue : IDBCursor {
readonly attribute any value;
};
return adoptRef(*new IDBCursor(transaction, index, info));
}
-IDBCursor::IDBCursor(IDBTransaction&, IDBObjectStore& objectStore, const IDBCursorInfo& info)
- : m_info(info)
+IDBCursor::IDBCursor(IDBTransaction& transaction, IDBObjectStore& objectStore, const IDBCursorInfo& info)
+ : ActiveDOMObject(transaction.scriptExecutionContext())
+ , m_info(info)
, m_source(IDBAny::create(objectStore).leakRef())
, m_objectStore(&objectStore)
{
+ suspendIfNeeded();
}
-IDBCursor::IDBCursor(IDBTransaction&, IDBIndex& index, const IDBCursorInfo& info)
- : m_info(info)
+IDBCursor::IDBCursor(IDBTransaction& transaction, IDBIndex& index, const IDBCursorInfo& info)
+ : ActiveDOMObject(transaction.scriptExecutionContext())
+ , m_info(info)
, m_source(IDBAny::create(index).leakRef())
, m_index(&index)
{
+ suspendIfNeeded();
}
IDBCursor::~IDBCursor()
ASSERT(request);
request->setSource(*this);
+ ++m_outstandingRequestCount;
+
return request;
}
void IDBCursor::uncheckedIterateCursor(const IDBKeyData& key, unsigned long count)
{
+ ++m_outstandingRequestCount;
+
m_request->willIterateCursor(*this);
transaction().iterateCursor(*this, key, count);
}
return nullptr;
}
- return effectiveObjectStore().deleteFunction(context, m_deprecatedCurrentPrimaryKey.jsValue(), ec);
+ auto request = effectiveObjectStore().modernDelete(context, m_deprecatedCurrentPrimaryKey.jsValue(), ec);
+ if (ec.code)
+ return nullptr;
+
+ ASSERT(request);
+ request->setSource(*this);
+ ++m_outstandingRequestCount;
+
+ return request;
}
void IDBCursor::setGetResult(IDBRequest& request, const IDBGetResult& getResult)
m_gotValue = true;
}
+const char* IDBCursor::activeDOMObjectName() const
+{
+ return "IDBCursor";
+}
+
+bool IDBCursor::canSuspendForDocumentSuspension() const
+{
+ return false;
+}
+
+bool IDBCursor::hasPendingActivity() const
+{
+ return m_outstandingRequestCount;
+}
+
+void IDBCursor::decrementOutstandingRequestCount()
+{
+ ASSERT(m_outstandingRequestCount);
+ --m_outstandingRequestCount;
+}
+
} // namespace IDBClient
} // namespace WebCore
class IDBObjectStore;
class IDBTransaction;
-class IDBCursor : public WebCore::IDBCursorWithValue {
+class IDBCursor : public WebCore::IDBCursorWithValue, public ActiveDOMObject {
public:
static Ref<IDBCursor> create(IDBTransaction&, IDBIndex&, const IDBCursorInfo&);
virtual bool isKeyCursor() const override { return true; }
virtual bool isModernCursor() const override final { return true; }
+ void decrementOutstandingRequestCount();
+
protected:
IDBCursor(IDBTransaction&, IDBObjectStore&, const IDBCursorInfo&);
IDBCursor(IDBTransaction&, IDBIndex&, const IDBCursorInfo&);
private:
+ // ActiveDOMObject.
+ virtual const char* activeDOMObjectName() const override final;
+ virtual bool canSuspendForDocumentSuspension() const override final;
+ virtual bool hasPendingActivity() const override final;
+
+ // Cursors are created with an outstanding iteration request.
+ unsigned m_outstandingRequestCount { 1 };
+
IDBCursorInfo m_info;
Ref<IDBAny> m_source;
IDBObjectStore* m_objectStore { nullptr };
return adoptRef(request.leakRef());
}
-
RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
{
+ return doDelete(context, keyRange, ec);
+}
+
+RefPtr<IDBRequest> IDBObjectStore::doDelete(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec)
+{
LOG(IndexedDB, "IDBObjectStore::deleteFunction");
// The IDB spec for several IDBObjectStore methods states that transaction related exceptions should fire before
RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage& ec)
{
- return deleteFunction(context, key.jsValue(), ec);
+ return modernDelete(context, key.jsValue(), ec);
}
-RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCodeWithMessage& ec)
+RefPtr<IDBRequest> IDBObjectStore::modernDelete(ScriptExecutionContext* context, JSC::JSValue key, ExceptionCodeWithMessage& ec)
{
DOMRequestState requestState(context);
RefPtr<IDBKey> idbKey = scriptValueToIDBKey(&requestState, key);
return nullptr;
}
- return deleteFunction(context, &IDBKeyRange::create(idbKey.get()).get(), ec);
+ return doDelete(context, &IDBKeyRange::create(idbKey.get()).get(), ec);
}
RefPtr<WebCore::IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, ExceptionCodeWithMessage& ec)
virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCodeWithMessage&) override final;
RefPtr<IDBRequest> putForCursorUpdate(JSC::ExecState&, JSC::JSValue, JSC::JSValue key, ExceptionCodeWithMessage&);
-
- RefPtr<WebCore::IDBRequest> deleteFunction(ScriptExecutionContext*, JSC::JSValue key, ExceptionCodeWithMessage&);
+ RefPtr<IDBRequest> modernDelete(ScriptExecutionContext*, JSC::JSValue key, ExceptionCodeWithMessage&);
void markAsDeleted();
bool isDeleted() const { return m_deleted; }
RefPtr<IDBRequest> putOrAdd(JSC::ExecState&, JSC::JSValue, RefPtr<IDBKey>, IndexedDB::ObjectStoreOverwriteMode, InlineKeyCheck, ExceptionCodeWithMessage&);
RefPtr<WebCore::IDBRequest> doCount(ScriptExecutionContext&, const IDBKeyRangeData&, ExceptionCodeWithMessage&);
+ RefPtr<IDBRequest> doDelete(ScriptExecutionContext* context, IDBKeyRange* keyRange, ExceptionCodeWithMessage& ec);
IDBObjectStoreInfo m_info;
IDBObjectStoreInfo m_originalInfo;
void IDBRequest::setSource(IDBCursor& cursor)
{
+ ASSERT(!m_cursorRequestNotifier);
+
m_source = IDBAny::create(cursor);
+ m_cursorRequestNotifier = std::make_unique<ScopeGuard>([this]() {
+ ASSERT(m_source->type() == IDBAny::Type::IDBCursor || m_source->type() == IDBAny::Type::IDBCursorWithValue);
+ m_source->modernIDBCursor()->decrementOutstandingRequestCount();
+ });
}
void IDBRequest::setVersionChangeTransaction(IDBTransaction& transaction)
m_hasPendingActivity = false;
+ m_cursorRequestNotifier = nullptr;
+
bool dontPreventDefault;
{
TransactionActivator activator(m_transaction.get());
ASSERT(m_transaction);
ASSERT(!m_pendingCursor);
ASSERT(&cursor == resultCursor());
+ ASSERT(!m_cursorRequestNotifier);
m_pendingCursor = &cursor;
m_hasPendingActivity = true;
m_readyState = IDBRequestReadyState::Pending;
m_domError = nullptr;
m_idbError = { };
+
+ m_cursorRequestNotifier = std::make_unique<ScopeGuard>([this]() {
+ m_pendingCursor->decrementOutstandingRequestCount();
+ });
}
void IDBRequest::didOpenOrIterateCursor(const IDBResultData& resultData)
m_result = IDBAny::create(*m_pendingCursor);
}
+ m_cursorRequestNotifier = nullptr;
m_pendingCursor = nullptr;
requestCompleted(resultData);
#include "IDBOpenDBRequest.h"
#include "IDBResourceIdentifier.h"
#include "IDBTransactionImpl.h"
+#include "ScopeGuard.h"
#include <wtf/RefCounted.h>
namespace WebCore {
IndexedDB::IndexRecordType m_requestedIndexRecordType;
RefPtr<IDBCursor> m_pendingCursor;
+
+ std::unique_ptr<ScopeGuard> m_cursorRequestNotifier;
};
} // namespace IDBClient
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "IDBServer.h"
#include "IDBTransactionInfo.h"
#include "Logging.h"
+#include "ScopeGuard.h"
#include "UniqueIDBDatabaseConnection.h"
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
return *globalObject.get()->globalExec();
}
-class ScopeGuard {
-public:
- ScopeGuard()
- {
- }
-
- ScopeGuard(std::function<void()> function)
- : m_function(WTFMove(function))
- {
- }
-
- ~ScopeGuard()
- {
- if (m_function)
- m_function();
- }
-
- void enable(std::function<void()> function)
- {
- m_function = WTFMove(function);
- }
-
- void disable()
- {
- m_function = nullptr;
- }
-
-private:
- std::function<void()> m_function { nullptr };
-};
-
void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const ThreadSafeDataBuffer& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
{
ASSERT(!isMainThread());
513F14540AB634C400094DDF /* IconLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 513F14520AB634C400094DDF /* IconLoader.h */; };
51405C88190B014400754F94 /* SelectionRectGatherer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51405C86190B014400754F94 /* SelectionRectGatherer.cpp */; };
51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */ = {isa = PBXBuildFile; fileRef = 51405C87190B014400754F94 /* SelectionRectGatherer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 5141298E1C5FD83A0059E714 /* JSIDBCursorWithValueCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */; };
+ 514129901C601ACC0059E714 /* ScopeGuard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5141298F1C601A890059E714 /* ScopeGuard.h */; settings = {ATTRIBUTES = (Private, ); }; };
5145B1091BC48E2E00E86219 /* IDBResourceIdentifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */; };
5145B10A1BC48E2E00E86219 /* IDBResourceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
5148453E1BB9D07E006A72ED /* IDBError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5148453C1BB9D076006A72ED /* IDBError.cpp */; };
513F14520AB634C400094DDF /* IconLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IconLoader.h; sourceTree = "<group>"; };
51405C86190B014400754F94 /* SelectionRectGatherer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRectGatherer.cpp; sourceTree = "<group>"; };
51405C87190B014400754F94 /* SelectionRectGatherer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRectGatherer.h; sourceTree = "<group>"; };
+ 5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorWithValueCustom.cpp; sourceTree = "<group>"; };
+ 5141298F1C601A890059E714 /* ScopeGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeGuard.h; sourceTree = "<group>"; };
5145B1071BC4890B00E86219 /* IDBResourceIdentifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBResourceIdentifier.cpp; sourceTree = "<group>"; };
5145B1081BC4890B00E86219 /* IDBResourceIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBResourceIdentifier.h; sourceTree = "<group>"; };
5148453C1BB9D076006A72ED /* IDBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBError.cpp; sourceTree = "<group>"; };
D6F7960C166FFECE0076DD18 /* JSHTMLTemplateElementCustom.cpp */,
511EF2CC17F0FDF100E4FA16 /* JSIDBAnyCustom.cpp */,
512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */,
+ 5141298D1C5FD7E90059E714 /* JSIDBCursorWithValueCustom.cpp */,
511EF2CD17F0FDF100E4FA16 /* JSIDBDatabaseCustom.cpp */,
511EF2CE17F0FDF100E4FA16 /* JSIDBObjectStoreCustom.cpp */,
A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
44C363EF0FAA7BB30097F8CC /* RuntimeApplicationChecksIOS.mm */,
5162C7F211F77EFA00612EFE /* SchemeRegistry.cpp */,
5162C7F311F77EFB00612EFE /* SchemeRegistry.h */,
+ 5141298F1C601A890059E714 /* ScopeGuard.h */,
BC8AE34C12EA096A00EB3AE6 /* ScrollableArea.cpp */,
BC8AE34D12EA096A00EB3AE6 /* ScrollableArea.h */,
CA3BF67B10D99BAE00E6CE53 /* ScrollAnimator.cpp */,
31C0FF4C0E4CEFDD007D6FE5 /* DOMWebKitTransitionEvent.h in Headers */,
31C0FF4E0E4CEFDD007D6FE5 /* DOMWebKitTransitionEventInternal.h in Headers */,
85C7F5E70AAFBAFB004014DD /* DOMWheelEvent.h in Headers */,
+ 514129901C601ACC0059E714 /* ScopeGuard.h in Headers */,
85989DD10ACC8BBD00A0BC51 /* DOMWheelEventInternal.h in Headers */,
1403B99709EB13AF00797C7F /* DOMWindow.h in Headers */,
FC9A0F75164094CF003D6B8D /* DOMWindowCSS.h in Headers */,
B5A684240FFABEAA00D24689 /* SQLiteFileSystem.cpp in Sources */,
1A22464B0CC98DDB00C05240 /* SQLiteStatement.cpp in Sources */,
1A22464D0CC98DDB00C05240 /* SQLiteTransaction.cpp in Sources */,
+ 5141298E1C5FD83A0059E714 /* JSIDBCursorWithValueCustom.cpp in Sources */,
97BC6A411505F081001B74AC /* SQLResultSet.cpp in Sources */,
97BC6A441505F081001B74AC /* SQLResultSetRowList.cpp in Sources */,
FE8A674716CDD19E00930BF8 /* SQLStatement.cpp in Sources */,
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSIDBCursorWithValue.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBCursorWithValueImpl.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSIDBCursorWithValue::visitAdditionalChildren(SlotVisitor& visitor)
+{
+ JSIDBCursor::visitAdditionalChildren(visitor);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ScopeGuard_h
+#define ScopeGuard_h
+
+namespace WebCore {
+
+class ScopeGuard {
+public:
+ ScopeGuard()
+ {
+ }
+
+ ScopeGuard(std::function<void()> function)
+ : m_function(WTFMove(function))
+ {
+ }
+
+ ~ScopeGuard()
+ {
+ if (m_function)
+ m_function();
+ }
+
+ void enable(std::function<void()> function)
+ {
+ m_function = WTFMove(function);
+ }
+
+ void disable()
+ {
+ m_function = nullptr;
+ }
+
+private:
+ std::function<void()> m_function { nullptr };
+};
+
+} // namespace WebCore
+
+#endif // ScopeGuard_h