void WorkerThreadableLoader::MainThreadBridge::cancel()
{
    m_loaderProxy.postTaskToLoader(createCallbackTask(&MainThreadBridge::mainThreadCancel, this));
    ThreadableLoaderClientWrapper* clientWrapper = m_workerClientWrapper.get();
    if (!clientWrapper->done()) {
        // If the client hasn't reached a termination state, then transition it by sending a cancellation error.
        // Note: no more client callbacks will be done after this method -- the clearClientWrapper() call ensures that.
        ResourceError error(String(), 0, String(), String());
        error.setIsCancellation(true);
        clientWrapper->didFail(error);
    }
    clearClientWrapper();
}
void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
{
    ASSERT(isMainThread());
    ASSERT_UNUSED(context, context->isDocument());

    RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;

    Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode);
    thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(
        createCallbackTask(&Bridge::setWebSocketChannel,
                           AllowCrossThreadAccess(thisPtr),
                           AllowCrossThreadAccess(peer), clientWrapper, peer->useHixie76Protocol()), taskMode);
}
void Database::runTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
    PassRefPtr<VoidCallback> successCallback, bool readOnly, const ChangeVersionData* changeVersionData)
{
    RefPtr<SQLTransactionErrorCallback> anotherRefToErrorCallback = errorCallback;
    RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, successCallback, anotherRefToErrorCallback, readOnly);

    RefPtr<SQLTransactionBackend> transactionBackend;
    transactionBackend = backend()->runTransaction(transaction.release(), readOnly, changeVersionData);
    if (!transactionBackend && anotherRefToErrorCallback) {
        RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed");
        scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, anotherRefToErrorCallback, error.release()));
    }
}
WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
    : m_workerClientWrapper(workerClientWrapper)
    , m_workerContext(workerContext)
    , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
    , m_taskMode(taskMode)
    , m_peer(0)
{
    ASSERT(m_workerClientWrapper.get());
    setMethodNotCompleted();
    m_loaderProxy.postTaskToLoader(createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel, this, m_workerClientWrapper, m_taskMode, url, protocol));
    waitForMethodCompletion();
    ASSERT(m_peer);
}
Exemple #5
0
void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type)
{
    // readAs*** methods() can be called multiple times. Only the last call before the actual reading happens is processed.
    if (m_state != None && m_state != Starting)
        return;

    if (m_state == None)
        scriptExecutionContext()->postTask(createCallbackTask(&delayedStart, this));

    m_blob = blob;
    m_readType = type;
    m_state = Starting;
}
void IDBDatabaseBackendImpl::runIntVersionChangeTransaction(int64_t requestedVersion, PassRefPtr<IDBCallbacks> prpCallbacks, PassRefPtr<IDBDatabaseCallbacks> prpDatabaseCallbacks)
{
    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    RefPtr<IDBDatabaseCallbacks> databaseCallbacks = prpDatabaseCallbacks;
    ASSERT(callbacks);
    for (DatabaseCallbacksSet::const_iterator it = m_databaseCallbacksSet.begin(); it != m_databaseCallbacksSet.end(); ++it) {
        // Front end ensures the event is not fired at connections that have closePending set.
        if (*it != databaseCallbacks)
            (*it)->onVersionChange(m_metadata.intVersion, requestedVersion);
    }
    // The spec dictates we wait until all the version change events are
    // delivered and then check m_databaseCallbacks.empty() before proceeding
    // or firing a blocked event, but instead we should be consistent with how
    // the old setVersion (incorrectly) did it.
    // FIXME: Remove the call to onBlocked and instead wait until the frontend
    // tells us that all the blocked events have been delivered. See
    // https://bugs.webkit.org/show_bug.cgi?id=71130
    if (connectionCount())
        callbacks->onBlocked(m_metadata.intVersion);
    // FIXME: Add test for m_runningVersionChangeTransaction.
    if (m_runningVersionChangeTransaction || connectionCount()) {
        m_pendingOpenWithVersionCalls.append(PendingOpenWithVersionCall::create(callbacks, databaseCallbacks, requestedVersion));
        return;
    }

    Vector<int64_t> objectStoreIds;
    RefPtr<IDBTransactionBackendInterface> transactionInterface = transaction(objectStoreIds, IDBTransaction::VERSION_CHANGE);
    RefPtr<IDBTransactionBackendImpl> transaction = IDBTransactionBackendImpl::from(transactionInterface.get());

    RefPtr<IDBDatabaseBackendImpl> database = this;
    OwnPtr<ScriptExecutionContext::Task> intVersionTask = createCallbackTask(&IDBDatabaseBackendImpl::setIntVersionInternal, database, requestedVersion, callbacks, databaseCallbacks, transaction);
    OwnPtr<ScriptExecutionContext::Task> resetVersionOnAbortTask = createCallbackTask(&IDBDatabaseBackendImpl::resetVersion, database, m_metadata.version, m_metadata.intVersion);
    if (!transaction->scheduleTask(intVersionTask.release(), resetVersionOnAbortTask.release())) {
        ASSERT_NOT_REACHED();
    }
    ASSERT(!m_pendingSecondHalfOpenWithVersion);
    m_databaseCallbacksSet.add(databaseCallbacks);
}
Exemple #7
0
void FileReader::abort()
{
    WTF_LOG(FileAPI, "FileReader: aborting\n");

    if (m_loadingState != LoadingStateLoading
        && m_loadingState != LoadingStatePending) {
        return;
    }
    m_loadingState = LoadingStateAborted;

    // Schedule to have the abort done later since abort() might be called from the event handler and we do not want the resource loading code to be in the stack.
    executionContext()->postTask(
        createCallbackTask(&delayedAbort, AllowAccessLater(this)));
}
Exemple #8
0
unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount()
{
    if (!m_workerClientWrapper)
        return 0;
    ASSERT(m_peer);
    setMethodNotCompleted();
    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadBufferedAmount, AllowCrossThreadAccess(m_peer)));
    RefPtr<Bridge> protect(this);
    waitForMethodCompletion();
    ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
    if (clientWrapper)
        return clientWrapper->bufferedAmount();
    return 0;
}
PassRefPtr<IDBObjectStoreBackendInterface>  IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
{
    ASSERT(transactionPtr->mode() == IDBTransaction::VERSION_CHANGE);

    if (m_objectStores.contains(name)) {
        ec = IDBDatabaseException::CONSTRAINT_ERR;
        return 0;
    }

    RefPtr<IDBObjectStoreBackendImpl> objectStore = IDBObjectStoreBackendImpl::create(m_sqliteDatabase.get(), name, keyPath, autoIncrement);
    ASSERT(objectStore->name() == name);

    RefPtr<IDBDatabaseBackendImpl> database = this;
    RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
    if (!transaction->scheduleTask(createCallbackTask(&IDBDatabaseBackendImpl::createObjectStoreInternal, database, objectStore, transaction),
                                   createCallbackTask(&IDBDatabaseBackendImpl::removeObjectStoreFromMap, database, objectStore))) {
        ec = IDBDatabaseException::NOT_ALLOWED_ERR;
        return 0;
    }

    m_objectStores.set(name, objectStore);
    return objectStore.release();
}
Exemple #10
0
void WebSharedWorkerImpl::connect(WebMessagePortChannel* webChannel, ConnectListener* listener)
{
    // Convert the WebMessagePortChanel to a WebCore::MessagePortChannel.
    RefPtr<PlatformMessagePortChannel> platform_channel =
        PlatformMessagePortChannel::create(webChannel);
    webChannel->setClient(platform_channel.get());
    OwnPtr<MessagePortChannel> channel =
        MessagePortChannel::create(platform_channel);

    workerThread()->runLoop().postTask(
        createCallbackTask(&connectTask, channel.release()));
    if (listener)
        listener->connected();
}
Exemple #11
0
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
{
    if (!m_workerClientWrapper)
        return ThreadableWebSocketChannel::SendFail;
    ASSERT(m_peer);
    setMethodNotCompleted();
    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size()));
    RefPtr<Bridge> protect(this);
    waitForMethodCompletion();
    ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
    if (!clientWrapper)
        return ThreadableWebSocketChannel::SendFail;
    return clientWrapper->sendRequestResult();
}
Exemple #12
0
void WorkerThreadableWebSocketChannel::Bridge::initialize(const String& sourceURL, unsigned lineNumber)
{
    RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound();
    m_peer = WeakPtr<Peer>(reference);

    OwnPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = ThreadableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->createWaitableEvent()));
    // This pointer is guaranteed to be valid until we call terminatePeer.
    m_syncHelper = syncHelper.get();

    RefPtr<Bridge> protect(this);
    if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, reference.release(), AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL, lineNumber, syncHelper.release()))) {
        // The worker thread has been signalled to shutdown before method completion.
        terminatePeer();
    }
}
Exemple #13
0
void ThreadableWebSocketChannelClientWrapper::processPendingTasks()
{
    if (m_suspended)
        return;
    if (!m_syncMethodDone) {
        // When a synchronous operation is in progress (i.e. the execution stack contains
        // WorkerThreadableWebSocketChannel::waitForMethodCompletion()), we cannot invoke callbacks in this run loop.
        m_context->postTask(createCallbackTask(&ThreadableWebSocketChannelClientWrapper::processPendingTasksCallback, this));
        return;
    }
    Vector<OwnPtr<ScriptExecutionContext::Task> > tasks;
    tasks.swap(m_pendingTasks);
    for (Vector<OwnPtr<ScriptExecutionContext::Task> >::const_iterator iter = tasks.begin(); iter != tasks.end(); ++iter)
        (*iter)->performTask(0);
}
bool WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
{
    if (!m_workerClientWrapper)
        return false;
    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>(binaryData.byteLength()));
    if (binaryData.byteLength())
        memcpy(data->data(), binaryData.data(), binaryData.byteLength());
    setMethodNotCompleted();
    m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendArrayBuffer, AllowCrossThreadAccess(m_peer), data.release()));
    RefPtr<Bridge> protect(this);
    waitForMethodCompletion();
    ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
    return clientWrapper && clientWrapper->sendRequestResult();
}
Exemple #15
0
void Database::runTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback,
                              PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
{
    MutexLocker locker(m_transactionInProgressMutex);
    if (!m_isTransactionQueueEnabled) {
        if (errorCallback) {
            RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed");
            scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, errorCallback, error.release()));
        }
        return;
    }
    RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, errorCallback, successCallback, wrapper, readOnly);
    m_transactionQueue.append(transaction.release());
    if (!m_transactionInProgress)
        scheduleTransaction();
}
void WebWorkerImpl::postMessageToWorkerContext(const WebString& message,
                                               const WebMessagePortChannelArray& webChannels)
{
    OwnPtr<MessagePortChannelArray> channels;
    if (webChannels.size()) {
        channels = new MessagePortChannelArray(webChannels.size());
        for (size_t i = 0; i < webChannels.size(); ++i) {
            RefPtr<PlatformMessagePortChannel> platform_channel =
                PlatformMessagePortChannel::create(webChannels[i]);
            webChannels[i]->setClient(platform_channel.get());
            (*channels)[i] = MessagePortChannel::create(platform_channel);
        }
    }

    workerThread()->runLoop().postTask(
        createCallbackTask(&postMessageToWorkerContextTask,
                           this, String(message), channels.release()));
}
Exemple #17
0
void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
    if (transaction->mode() == IDBTransaction::READ_ONLY) {
        ec = IDBDatabaseException::READ_ONLY_ERR;
        return;
    }

    RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
    RefPtr<IDBKey> key = prpKey;
    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
    if (!key || !key->valid()) {
        ec = IDBDatabaseException::DATA_ERR;
        return;
    }

    if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::deleteInternal, objectStore, key, callbacks)))
        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
}
void WebWorkerClientImpl::startWorkerContext(const KURL& scriptURL,
                                             const String& userAgent,
                                             const String& sourceCode)
{
    // Worker.terminate() could be called from JS before the context is started.
    if (m_askedToTerminate)
        return;
    if (!isMainThread()) {
        WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(
            &startWorkerContextTask,
            AllowCrossThreadAccess(this),
            scriptURL.string(),
            userAgent,
            sourceCode));
        return;
    }
    m_webWorker->startWorkerContext(scriptURL, userAgent, sourceCode);
}
void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMessage,
                                                      int lineNumber,
                                                      const WebString& sourceURL)
{
    if (currentThread() != m_workerThreadId) {
        m_scriptExecutionContext->postTask(createCallbackTask(&postExceptionToWorkerObjectTask,
                                                              AllowCrossThreadAccess(this),
                                                              String(errorMessage),
                                                              lineNumber,
                                                              String(sourceURL)));
        return;
    }

    bool unhandled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage,
                                                                sourceURL,
                                                                lineNumber));
    if (unhandled)
        m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL, 0);
}
void IDBCursorBackendImpl::continueFunction(PassRefPtr<IDBKey> prpKey, PassRefPtr<IDBCallbacks> prpCallbacks, ExceptionCode& ec)
{
    IDB_TRACE("IDBCursorBackendImpl::continue");
    RefPtr<IDBKey> key = prpKey;

    if (m_cursor && key) {
        ASSERT(m_cursor->key());
        if (m_direction == IDBCursor::NEXT || m_direction == IDBCursor::NEXT_NO_DUPLICATE) {
            if (!m_cursor->key()->isLessThan(key.get())) {
                ec = IDBDatabaseException::DATA_ERR;
                return;
            }
        } else {
            if (!key->isLessThan(m_cursor->key().get())) {
                ec = IDBDatabaseException::DATA_ERR;
                return;
            }
        }
    }

    if (!m_transaction->scheduleTask(createCallbackTask(&IDBCursorBackendImpl::continueFunctionInternal, this, key, prpCallbacks)))
        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
}
void WebWorkerClientImpl::postMessageToWorkerContext(
    PassRefPtr<SerializedScriptValue> message,
    PassOwnPtr<MessagePortChannelArray> channels)
{
    // Worker.terminate() could be called from JS before the context is started.
    if (m_askedToTerminate)
        return;
    ++m_unconfirmedMessageCount;
    if (!isMainThread()) {
        WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&postMessageToWorkerContextTask,
                                                                   AllowCrossThreadAccess(this),
                                                                   message->toWireString(),
                                                                   channels));
        return;
    }
    WebMessagePortChannelArray webChannels(channels.get() ? channels->size() : 0);
    for (size_t i = 0; i < webChannels.size(); ++i) {
        WebMessagePortChannel* webchannel =
                        (*channels)[i]->channel()->webChannelRelease();
        webchannel->setClient(0);
        webChannels[i] = webchannel;
    }
    m_webWorker->postMessageToWorkerContext(message->toWireString(), webChannels);
}
Exemple #22
0
void ThreadableWebSocketChannelClientWrapper::didConnect()
{
    m_pendingTasks.append(createCallbackTask(&didConnectCallback, this));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #23
0
void WorkerMessagingProxy::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
{
    m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageTask, this, source, type, level, message, lineNumber, sourceURL));
}
Exemple #24
0
void IDBObjectStoreBackendImpl::count(PassRefPtr<IDBKeyRange> range, PassRefPtr<IDBCallbacks> callbacks, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
    if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::countInternal, this, range, callbacks, transaction)))
        ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
}
Exemple #25
0
void ThreadableWebSocketChannelClientWrapper::didReceiveMessage(const String& message)
{
    m_pendingTasks.append(createCallbackTask(&didReceiveMessageCallback, this, message));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #26
0
void ThreadableWebSocketChannelClientWrapper::didReceiveMessageError()
{
    m_pendingTasks.append(createCallbackTask(&didReceiveMessageErrorCallback, this));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #27
0
void ThreadableWebSocketChannelClientWrapper::didClose(unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
{
    m_pendingTasks.append(createCallbackTask(&didCloseCallback, this, unhandledBufferedAmount, closingHandshakeCompletion, code, reason));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #28
0
void ThreadableWebSocketChannelClientWrapper::didStartClosingHandshake()
{
    m_pendingTasks.append(createCallbackTask(&didStartClosingHandshakeCallback, this));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #29
0
void ThreadableWebSocketChannelClientWrapper::didUpdateBufferedAmount(unsigned long bufferedAmount)
{
    m_pendingTasks.append(createCallbackTask(&didUpdateBufferedAmountCallback, this, bufferedAmount));
    if (!m_suspended)
        processPendingTasks();
}
Exemple #30
0
void ThreadableWebSocketChannelClientWrapper::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData)
{
    m_pendingTasks.append(createCallbackTask(&didReceiveBinaryDataCallback, this, binaryData));
    if (!m_suspended)
        processPendingTasks();
}