void Database::runTransaction( SQLTransactionCallback* callback, SQLTransactionErrorCallback* errorCallback, VoidCallback* successCallback, bool readOnly, const ChangeVersionData* changeVersionData) { ASSERT(executionContext()->isContextThread()); // 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(BLINK_FROM_HERE, createSameThreadTask(&callTransactionErrorCallback, callback, error.release())); } } }
void PopupMenuImpl::updateFromElement() { if (m_needsUpdate) return; m_needsUpdate = true; ownerElement().document().postTask(BLINK_FROM_HERE, createSameThreadTask(&PopupMenuImpl::update, PassRefPtrWillBeRawPtr<PopupMenuImpl>(this))); }
void AudioContext::setContextState(AudioContextState newState) { ASSERT(isMainThread()); // Validate the transitions. The valid transitions are Suspended->Running, Running->Suspended, // and anything->Closed. switch (newState) { case Suspended: ASSERT(m_contextState == Running); break; case Running: ASSERT(m_contextState == Suspended); break; case Closed: ASSERT(m_contextState != Closed); break; } if (newState == m_contextState) { // ASSERTs above failed; just return. return; } m_contextState = newState; // Notify context that state changed if (executionContext()) executionContext()->postTask(FROM_HERE, createSameThreadTask(&AudioContext::notifyStateChange, this)); }
void PopupMenuImpl::updateFromElement(UpdateReason) { if (m_needsUpdate) return; m_needsUpdate = true; ownerElement().document().postTask( BLINK_FROM_HERE, createSameThreadTask(&PopupMenuImpl::update, wrapPersistent(this))); }
void DOMFileSystem::reportError(ExecutionContext* executionContext, ErrorCallbackBase* errorCallback, FileError::ErrorCode fileError) { if (errorCallback) scheduleCallback( executionContext, createSameThreadTask(&ErrorCallbackBase::invoke, wrapPersistent(errorCallback), fileError)); }
void ContentDecryptionModuleResultPromise::reject(ExceptionCode code, const String& errorMessage) { // Reject the promise asynchronously. This avoids problems when gc is // destroying objects that result in unfulfilled promises being rejected. // (Resolving promises is still done synchronously as there may be events // already posted that need to happen only after the promise is resolved.) // TODO(jrummell): Make resolving a promise asynchronous as well (including // making sure events still happen after the promise is resolved). getExecutionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&ContentDecryptionModuleResultPromise::rejectInternal, wrapPersistent(this), code, errorMessage)); }
void ExecutionContext::resumeScheduledTasks() { resumeActiveDOMObjects(); tasksWereResumed(); // We need finish stack unwiding before running next task because it can suspend this context. if (m_isRunSuspendableTasksScheduled) return; m_isRunSuspendableTasksScheduled = true; postTask(FROM_HERE, createSameThreadTask(&ExecutionContext::runSuspendableTasks, this)); }
TEST(MainThreadTaskRunnerTest, PostTask) { RawPtr<NullExecutionContext> context = new NullExecutionContext(); RawPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get()); bool isMarked = false; runner->postTask(BLINK_FROM_HERE, createSameThreadTask(&markBoolean, &isMarked)); EXPECT_FALSE(isMarked); blink::testing::runPendingTasks(); EXPECT_TRUE(isMarked); }
void ExternalPopupMenu::updateFromElement() { if (m_needsUpdate) return; // TOOD(tkent): Even if DOMTreeVersion is not changed, we should update the // popup location/content in some cases. e.g. Updating ComputedStyle of the // SELECT element affects popup position and OPTION style. if (m_shownDOMTreeVersion == m_ownerElement->document().domTreeVersion()) return; m_needsUpdate = true; m_ownerElement->document().postTask(BLINK_FROM_HERE, createSameThreadTask(&ExternalPopupMenu::update, PassRefPtrWillBeRawPtr<ExternalPopupMenu>(this))); }
TEST(MainThreadTaskRunnerTest, RemoveRunner) { RawPtr<NullExecutionContext> context = new NullExecutionContext(); RawPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get()); bool isMarked = false; context->setTasksNeedSuspension(true); runner->postTask(BLINK_FROM_HERE, createSameThreadTask(&markBoolean, &isMarked)); runner.clear(); blink::testing::runPendingTasks(); EXPECT_FALSE(isMarked); }
bool WorkerEventQueue::enqueueEvent(Event* event) { if (m_isClosed) return false; InspectorInstrumentation::asyncTaskScheduled( event->target()->getExecutionContext(), event->type(), event); m_pendingEvents.add(event); m_executionContext->postTask( BLINK_FROM_HERE, createSameThreadTask(&WorkerEventQueue::dispatchEvent, wrapPersistent(this), wrapWeakPersistent(event))); return true; }
void Sensor::updateState(Sensor::SensorState newState) { if (newState == m_state) return; m_state = newState; if (getExecutionContext()) { getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifyStateChanged, wrapWeakPersistent(this))); } updatePollingStatus(); }
void Sensor::reportError(ExceptionCode code, const String& sanitizedMessage, const String& unsanitizedMessage) { updateState(Sensor::SensorState::Errored); if (getExecutionContext()) { auto error = DOMException::create(code, sanitizedMessage, unsanitizedMessage); getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifyError, wrapWeakPersistent(this), wrapPersistent(error))); } }
void Sensor::updateState(Sensor::SensorState newState) { if (newState == m_state) return; if (newState == SensorState::Activated && getExecutionContext()) { DCHECK_EQ(SensorState::Activating, m_state); getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifyOnActivate, wrapWeakPersistent(this))); } m_state = newState; }
void SearchInputType::startSearchEventTimer() { ASSERT(element().layoutObject()); unsigned length = element().innerEditorValue().length(); if (!length) { stopSearchEventTimer(); element().document().postTask(BLINK_FROM_HERE, createSameThreadTask(&HTMLInputElement::onSearch, PassRefPtrWillBeRawPtr<HTMLInputElement>(&element()))); return; } // After typing the first key, we wait 0.5 seconds. // After the second key, 0.4 seconds, then 0.3, then 0.2 from then on. m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length), BLINK_FROM_HERE); }
void Sensor::onSensorUpdateNotification() { if (m_state != Sensor::SensorState::Activated) return; DCHECK(m_sensorProxy); DCHECK(m_sensorProxy->isInitialized()); DCHECK(m_sensorProxy->sensorReading()); if (getExecutionContext() && m_sensorProxy->sensorReading()->isReadingUpdated(m_storedData)) { getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifySensorReadingChanged, wrapWeakPersistent(this))); } m_storedData = m_sensorProxy->sensorReading()->data(); }
void Notification::close() { if (m_state != NotificationStateShowing) return; if (m_persistentId == kInvalidPersistentId) { // Fire the close event asynchronously. executionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&Notification::dispatchCloseEvent, this)); m_state = NotificationStateClosing; notificationManager()->close(this); } else { m_state = NotificationStateClosed; SecurityOrigin* origin = executionContext()->securityOrigin(); ASSERT(origin); notificationManager()->closePersistent(WebSecurityOrigin(origin), m_persistentId); } }
void Sensor::pollForData() { if (m_state != Sensor::SensorState::ACTIVE) { DCHECK(m_polling); m_polling->stopPolling(); return; } DCHECK(m_sensorProxy); DCHECK(m_sensorProxy->isInitialized()); m_sensorProxy->updateSensorReading(); DCHECK(m_sensorProxy->sensorReading()); if (getExecutionContext() && m_sensorProxy->sensorReading()->isReadingUpdated(m_storedData)) { getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Sensor::notifySensorReadingChanged, wrapWeakPersistent(this))); } m_storedData = m_sensorProxy->sensorReading()->data(); }
void DirectoryReader::readEntries(EntriesCallback* entriesCallback, ErrorCallback* errorCallback) { if (!m_isReading) { m_isReading = true; filesystem()->readDirectory(this, m_fullPath, new EntriesCallbackHelper(this), new ErrorCallbackHelper(this)); } if (m_error) { filesystem()->reportError(ScriptErrorCallback::wrap(errorCallback), m_error); return; } if (m_entriesCallback) { // Non-null m_entriesCallback means multiple readEntries() calls are made // concurrently. We don't allow doing it. filesystem()->reportError(ScriptErrorCallback::wrap(errorCallback), FileError::kInvalidStateErr); return; } if (!m_hasMoreEntries || !m_entries.isEmpty()) { if (entriesCallback) DOMFileSystem::scheduleCallback( filesystem()->getExecutionContext(), createSameThreadTask(&EntriesCallback::handleEvent, wrapPersistent(entriesCallback), PersistentHeapVector<Member<Entry>>(m_entries))); m_entries.clear(); return; } m_entriesCallback = entriesCallback; m_errorCallback = errorCallback; }
Database* DatabaseManager::openDatabase(ExecutionContext* context, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize, DatabaseCallback* creationCallback, DatabaseError& error, String& errorMessage) { ASSERT(error == DatabaseError::None); bool setVersionInNewDatabase = !creationCallback; Database* database = openDatabaseInternal(context, name, expectedVersion, displayName, estimatedSize, setVersionInNewDatabase, error, errorMessage); if (!database) return nullptr; databaseContextFor(context)->setHasOpenDatabases(); DatabaseClient::from(context)->didOpenDatabase(database, context->getSecurityOrigin()->host(), name, expectedVersion); if (database->isNew() && creationCallback) { WTF_LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database); database->getExecutionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&databaseCallbackHandleEvent, wrapPersistent(creationCallback), wrapPersistent(database)), "openDatabase"); } ASSERT(database); return database; }
void Notification::close() { if (m_state != State::Showing) return; // Schedule the "close" event to be fired for non-persistent notifications. // Persistent notifications won't get such events for programmatic closes. if (m_type == Type::NonPersistent) { getExecutionContext()->postTask( BLINK_FROM_HERE, createSameThreadTask(&Notification::dispatchCloseEvent, wrapPersistent(this))); m_state = State::Closing; notificationManager()->close(this); return; } m_state = State::Closed; SecurityOrigin* origin = getExecutionContext()->getSecurityOrigin(); DCHECK(origin); notificationManager()->closePersistent(WebSecurityOrigin(origin), m_data.tag, m_notificationId); }
void LocalFileSystem::fileSystemNotAvailable( RawPtr<ExecutionContext> context, CallbackWrapper* callbacks) { context->postTask(BLINK_FROM_HERE, createSameThreadTask(&reportFailure, callbacks->release(), FileError::ABORT_ERR)); }
void LocalFileSystem::fileSystemNotAllowedInternal( ExecutionContext* context, CallbackWrapper* callbacks) { context->postTask(BLINK_FROM_HERE, createSameThreadTask(&reportFailure, passed(callbacks->release()), FileError::ABORT_ERR)); }
void ExecutionContext::postSuspendableTask(PassOwnPtr<SuspendableTask> task) { m_suspendedTasks.append(task); if (!m_activeDOMObjectsAreSuspended) postTask(FROM_HERE, createSameThreadTask(&ExecutionContext::runSuspendableTasks, this)); }