TEST_F(CrossThreadTaskTest, CreateForFunctionWithExecutionContext) { OwnPtr<ExecutionContextTask> task1 = createCrossThreadTask(&functionWithExecutionContext, new GCObject); OwnPtr<ExecutionContextTask> task2 = createCrossThreadTask(&functionWithExecutionContext, RawPtr<GCObject>(new GCObject)); Heap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, BlinkGC::ForcedGC); EXPECT_EQ(2, GCObject::s_counter); }
void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode) { ASSERT(!isMainThread()); LOG(IndexedDB, "(db) UniqueIDBDatabase::performPutOrAdd"); ASSERT(m_backingStore); ASSERT(objectStoreIdentifier); IDBKeyData usedKey; IDBError error; auto objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier); if (!objectStoreInfo) { error = IDBError(IDBExceptionCode::InvalidStateError, ASCIILiteral("Object store cannot be found in the backing store")); m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey)); return; } if (objectStoreInfo->autoIncrement() && !keyData.isValid()) { uint64_t keyNumber; error = m_backingStore->generateKeyNumber(transactionIdentifier, objectStoreIdentifier, keyNumber); if (!error.isNull()) { m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey)); return; } usedKey.setNumberValue(keyNumber); } else usedKey = keyData; if (overwriteMode == IndexedDB::ObjectStoreOverwriteMode::NoOverwrite) { bool keyExists; error = m_backingStore->keyExistsInObjectStore(transactionIdentifier, objectStoreIdentifier, usedKey, keyExists); if (error.isNull() && keyExists) error = IDBError(IDBExceptionCode::ConstraintError, ASCIILiteral("Key already exists in the object store")); if (!error.isNull()) { m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey)); return; } } // 3.4.1 Object Store Storage Operation // ...If a record already exists in store ... // then remove the record from store using the steps for deleting records from an object store... // This is important because formally deleting it from from the object store also removes it from the appropriate indexes. error = m_backingStore->deleteRange(transactionIdentifier, objectStoreIdentifier, usedKey); if (!error.isNull()) { m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey)); return; } error = m_backingStore->addRecord(transactionIdentifier, objectStoreIdentifier, usedKey, valueData); m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey)); }
void UniqueIDBDatabase::getRecord(const IDBRequestData& requestData, const IDBKeyRangeData& range, GetResultCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord"); uint64_t callbackID = storeCallback(callback); if (uint64_t indexIdentifier = requestData.indexIdentifier()) m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetIndexRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), indexIdentifier, requestData.indexRecordType(), range)); else m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), range)); }
void WebSharedWorkerImpl::postMessageToPageInspector(const String& message) { m_mainFrame->frame()->document()->postInspectorTask( BLINK_FROM_HERE, createCrossThreadTask( &WebSharedWorkerImpl::postMessageToPageInspectorOnMainThread, crossThreadUnretained(this), message)); }
void Bridge::initialize(const String& sourceURL, unsigned lineNumber) { if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, m_peer.get(), sourceURL, lineNumber))) { // The worker thread has been signalled to shutdown before method completion. disconnect(); } }
void WorkerMessagingProxy::disconnectFromInspector() { m_pageInspector = 0; if (m_askedToTerminate) return; m_workerThread->postDebuggerTask(createCrossThreadTask(disconnectFromWorkerGlobalScopeInspectorTask, true)); }
// Invoked to notify us that there are messages available for this port. // This code may be called from another thread, and so should not call any // non-threadsafe APIs (i.e. should not call into the entangled channel or // access mutable variables). void MessagePort::messageAvailable() { DCHECK(getExecutionContext()); getExecutionContext()->postTask( BLINK_FROM_HERE, createCrossThreadTask(&MessagePort::dispatchMessages, wrapCrossThreadWeakPersistent(this))); }
void WorkerMessagingProxy::sendMessageToInspector(const String& message) { if (m_askedToTerminate) return; m_workerThread->postDebuggerTask(createCrossThreadTask(dispatchOnInspectorBackendTask, String(message))); m_workerThread->interruptAndDispatchInspectorCommands(); }
void UniqueIDBDatabase::performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo& info) { LOG(IndexedDB, "(db) UniqueIDBDatabase::performActivateTransactionInBackingStore"); IDBError error = m_backingStore->beginTransaction(info); m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformActivateTransactionInBackingStore, callbackIdentifier, error)); }
void Database::runTransaction( SQLTransactionCallback* callback, SQLTransactionErrorCallback* errorCallback, VoidCallback* successCallback, bool readOnly, const ChangeVersionData* changeVersionData) { // FIXME: Rather than passing errorCallback to SQLTransaction and then // sometimes firing it ourselves, this code should probably be pushed down // into Database so that we only create the SQLTransaction if we're // actually going to run it. #if ENABLE(ASSERT) SQLTransactionErrorCallback* originalErrorCallback = errorCallback; #endif SQLTransaction* transaction = SQLTransaction::create(this, callback, successCallback, errorCallback, readOnly); SQLTransactionBackend* transactionBackend = runTransaction(transaction, readOnly, changeVersionData); if (!transactionBackend) { SQLTransactionErrorCallback* callback = transaction->releaseErrorCallback(); ASSERT(callback == originalErrorCallback); if (callback) { OwnPtr<SQLErrorData> error = SQLErrorData::create(SQLError::UNKNOWN_ERR, "database has been closed"); executionContext()->postTask(createCrossThreadTask(&callTransactionErrorCallback, callback, error.release())); } } }
void UniqueIDBDatabase::deleteRecord(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord"); uint64_t callbackID = storeCallback(callback); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyRangeData)); }
void AudioScheduledSourceHandler::finish() { finishWithoutOnEnded(); if (m_hasEndedListener && context()->executionContext()) { context()->executionContext()->postTask(FROM_HERE, createCrossThreadTask(&AudioScheduledSourceHandler::notifyEnded, PassRefPtr<AudioScheduledSourceHandler>(this))); } }
void WorkerMessagingProxy::connectToInspector(WorkerGlobalScopeProxy::PageInspector* pageInspector) { if (m_askedToTerminate) return; ASSERT(!m_pageInspector); m_pageInspector = pageInspector; m_workerThread->postDebuggerTask(createCrossThreadTask(connectToWorkerGlobalScopeInspectorTask, true)); }
void UniqueIDBDatabase::performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier) { ASSERT(!isMainThread()); LOG(IndexedDB, "(db) UniqueIDBDatabase::performAbortTransaction"); IDBError error = m_backingStore->abortTransaction(transactionIdentifier); m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformAbortTransaction, callbackIdentifier, error, transactionIdentifier)); }
void UniqueIDBDatabase::getCount(const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount"); uint64_t callbackID = storeCallback(callback); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), requestData.indexIdentifier(), range)); }
void UniqueIDBDatabase::clearObjectStore(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, ErrorCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore"); uint64_t callbackID = storeCallback(callback); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performClearObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier)); }
void UniqueIDBDatabase::createIndex(UniqueIDBDatabaseTransaction& transaction, const IDBIndexInfo& info, ErrorCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::createIndex"); uint64_t callbackID = storeCallback(callback); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info)); }
void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback) { ASSERT(isMainThread()); LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd"); uint64_t callbackID = storeCallback(callback); m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, valueData, overwriteMode)); }
void WorkerMessagingProxy::workerObjectDestroyed() { // workerObjectDestroyed() is called in InProcessWorkerBase's destructor. // Thus it should be guaranteed that a weak pointer m_workerObject has been cleared // before this method gets called. ASSERT(!m_workerObject); m_executionContext->postTask(FROM_HERE, createCrossThreadTask(&WorkerMessagingProxy::workerObjectDestroyedInternal, this)); }
void UniqueIDBDatabase::performDeleteRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData& range) { ASSERT(!isMainThread()); LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteRecord"); IDBError error = m_backingStore->deleteRange(transactionIdentifier, objectStoreIdentifier, range); m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteRecord, callbackIdentifier, error)); }
void MemoryCache::removeURLFromCache(ExecutionContext* context, const KURL& url) { if (context->isWorkerGlobalScope()) { WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); workerGlobalScope->thread()->workerLoaderProxy().postTaskToLoader(createCrossThreadTask(&removeURLFromCacheInternal, url)); return; } removeURLFromCacheInternal(context, url); }
void Bridge::send(const CString& message) { ASSERT(m_peer); OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(message.length())); if (message.length()) memcpy(data->data(), static_cast<const char*>(message.data()), message.length()); m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::sendTextAsCharVector, m_peer.get(), data.release())); }
void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) { ASSERT(isMainThread()); if (m_mainWebSocketChannel) { m_mainWebSocketChannel->disconnect(); m_mainWebSocketChannel = nullptr; } m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidClose, m_bridge, closingHandshakeCompletion, code, reason)); }
void WorkerThreadableLoader::MainThreadBridge::destroy() { // Ensure that no more client callbacks are done in the worker context's thread. clearClientWrapper(); // "delete this" and m_mainThreadLoader::deref() on the worker object's thread. m_loaderProxy->postTaskToLoader( createCrossThreadTask(&MainThreadBridge::mainThreadDestroy, this)); }
void OfflineAudioDestinationHandler::finishOfflineRendering() { ASSERT(!isMainThread()); // The actual rendering has been completed. Notify the context. if (context()->executionContext()) { context()->executionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&OfflineAudioDestinationHandler::notifyComplete, this)); } }
void WorkerMessagingProxy::writeTimelineStartedEvent(const String& sessionId) { if (m_askedToTerminate) return; OwnPtr<ExecutionContextTask> task = createCrossThreadTask(dispatchWriteTimelineStartedEvent, String(sessionId)); if (m_workerThread) m_workerThread->postTask(task.release()); else m_queuedEarlyTasks.append(task.release()); }
void Bridge::send(const DOMArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) { ASSERT(m_peer); // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(byteLength)); if (binaryData.byteLength()) memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteOffset, byteLength); m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::sendBinaryAsCharVector, m_peer.get(), data.release())); }
bool Bridge::connect(const KURL& url, const String& protocol) { if (!m_peer) return false; if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer.get(), url, protocol))) return false; return m_syncHelper->connectRequestResult(); }
void IDBServer::performCloseAndDeleteDatabasesModifiedSince(std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { if (!m_databaseDirectoryPath.isEmpty()) { Vector<String> originPaths = listDirectory(m_databaseDirectoryPath, "*"); for (auto& originPath : originPaths) removeAllDatabasesForOriginPath(originPath, modifiedSince); } postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::didPerformCloseAndDeleteDatabases, callbackID)); }
void AudioScheduledSourceHandler::finish() { finishWithoutOnEnded(); if (context()->getExecutionContext()) { context()->getExecutionContext()->postTask( BLINK_FROM_HERE, createCrossThreadTask(&AudioScheduledSourceHandler::notifyEnded, PassRefPtr<AudioScheduledSourceHandler>(this))); } }