ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) { if (!m_workerClientWrapper || !m_peer) return ThreadableWebSocketChannel::SendFail; // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. Vector<char>* dataPtr = std::make_unique<Vector<char>>(byteLength).release(); if (binaryData.byteLength()) memcpy(dataPtr->data(), static_cast<const char*>(binaryData.data()) + byteOffset, byteLength); setMethodNotCompleted(); Peer* peer = m_peer; m_loaderProxy.postTaskToLoader([peer, dataPtr] (ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); std::unique_ptr<Vector<char>> data(dataPtr); RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::create(data->data(), data->size()); peer->send(*arrayBuffer); }); Ref<Bridge> protect(*this); waitForMethodCompletion(); ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); if (!clientWrapper) return ThreadableWebSocketChannel::SendFail; return clientWrapper->sendRequestResult(); }
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(); } }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Blob& binaryData) { if (!m_workerClientWrapper || !m_peer) return ThreadableWebSocketChannel::SendFail; setMethodNotCompleted(); Peer* peer = m_peer; URLCapture capturedURL(binaryData.url()); StringCapture capturedType(binaryData.type()); long long size = binaryData.size(); m_loaderProxy.postTaskToLoader([peer, capturedURL, capturedType, size] (ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); peer->send(Blob::deserialize(capturedURL.url(), capturedType.string(), size)); }); Ref<Bridge> protect(*this); waitForMethodCompletion(); ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); if (!clientWrapper) return ThreadableWebSocketChannel::SendFail; return clientWrapper->sendRequestResult(); }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Blob& binaryData) { if (!m_workerClientWrapper || !m_peer) return ThreadableWebSocketChannel::SendFail; setMethodNotCompleted(); Peer* peer = m_peer; URL urlCopy = binaryData.url().copy(); String typeCopy = binaryData.type().isolatedCopy(); long long size = binaryData.size(); m_loaderProxy.postTaskToLoader([=](ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); RefPtr<Blob> blob = Blob::deserialize(urlCopy, typeCopy, size); peer->send(*blob); }); Ref<Bridge> protect(*this); waitForMethodCompletion(); ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); if (!clientWrapper) return ThreadableWebSocketChannel::SendFail; return clientWrapper->sendRequestResult(); }
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(); }
WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message) { if (!m_workerClientWrapper || !m_workerGlobalScope) return WebSocketChannel::SendFail; ASSERT(m_syncHelper); m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::send, m_peer, message.isolatedCopy()))); RefPtr<Bridge> protect(this); waitForMethodCompletion(); return m_syncHelper->sendRequestResult(); }
WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(PassRefPtr<BlobDataHandle> data) { if (!m_workerClientWrapper || !m_workerGlobalScope) return WebSocketChannel::SendFail; ASSERT(m_syncHelper); m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data))); RefPtr<Bridge> protect(this); waitForMethodCompletion(); return m_syncHelper->sendRequestResult(); }
unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() { if (!m_workerClientWrapper || !m_workerGlobalScope) return 0; ASSERT(m_syncHelper); m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::bufferedAmount, m_peer))); RefPtr<Bridge> protect(this); waitForMethodCompletion(); return m_syncHelper->bufferedAmount(); }
unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() { if (hasTerminatedPeer()) return 0; RefPtr<Bridge> protect(this); if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::bufferedAmount, m_peer)))) return 0; return m_syncHelper->bufferedAmount(); }
WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(PassRefPtr<BlobDataHandle> data) { if (hasTerminatedPeer()) return WebSocketChannel::SendFail; RefPtr<Bridge> protect(this); if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data)))) return WebSocketChannel::SendFail; return m_syncHelper->sendRequestResult(); }
WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message) { if (hasTerminatedPeer()) return WebSocketChannel::SendFail; RefPtr<Bridge> protect(this); if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::send, m_peer, message.isolatedCopy())))) return WebSocketChannel::SendFail; return m_syncHelper->sendRequestResult(); }
bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const String& protocol) { if (hasTerminatedPeer()) return false; RefPtr<Bridge> protect(this); if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::connect, m_peer, url.copy(), protocol.isolatedCopy())))) return false; return m_syncHelper->connectRequestResult(); }
bool WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData) { if (!m_workerClientWrapper) return false; 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(); return clientWrapper && clientWrapper->sendRequestResult(); }
void WorkerThreadableWebSocketChannel::Bridge::initialize() { ASSERT(!m_peer); setMethodNotCompleted(); Ref<Bridge> protect(*this); m_loaderProxy.postTaskToLoader(CrossThreadTask(&Bridge::mainThreadInitialize, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode)); waitForMethodCompletion(); // m_peer may be null when the nested runloop exited before a peer has created. m_peer = m_workerClientWrapper->peer(); if (!m_peer) m_workerClientWrapper->setFailedWebSocketChannelCreation(); }
bool WorkerThreadableWebSocketChannel::Bridge::send(const String& message) { if (!m_workerClientWrapper) return false; ASSERT(m_peer); setMethodNotCompleted(); m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message)); RefPtr<Bridge> protect(this); waitForMethodCompletion(); ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); return clientWrapper && clientWrapper->sent(); }
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); }
WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) { if (!m_workerClientWrapper || !m_workerGlobalScope) return WebSocketChannel::SendFail; ASSERT(m_syncHelper); // 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(CallClosureTask::create(bind(&Peer::sendArrayBuffer, m_peer, data.release()))); RefPtr<Bridge> protect(this); waitForMethodCompletion(); return m_syncHelper->sendRequestResult(); }
void Bridge::disconnect() { if (!m_peer) return; waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, m_peer.get())); // Here |m_peer| is detached from the main thread and we can delete it. m_client = nullptr; m_peer = nullptr; m_syncHelper = nullptr; // We won't use this any more. m_workerGlobalScope.clear(); }
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; }
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(); } }
void WorkerThreadableWebSocketChannel::Bridge::initialize() { ASSERT(!m_peer); setMethodNotCompleted(); Ref<Bridge> protectedThis(*this); m_loaderProxy.postTaskToLoader([&loaderProxy = m_loaderProxy, workerClientWrapper = m_workerClientWrapper.copyRef(), taskMode = m_taskMode.isolatedCopy()](ScriptExecutionContext& context) mutable { mainThreadInitialize(context, loaderProxy, WTFMove(workerClientWrapper), taskMode); }); waitForMethodCompletion(); // m_peer may be null when the nested runloop exited before a peer has created. m_peer = m_workerClientWrapper->peer(); if (!m_peer) m_workerClientWrapper->setFailedWebSocketChannelCreation(); }
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(); }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Blob& binaryData) { if (!m_peer) return ThreadableWebSocketChannel::SendFail; setMethodNotCompleted(); m_loaderProxy.postTaskToLoader([peer = m_peer, url = binaryData.url().isolatedCopy(), type = binaryData.type().isolatedCopy(), size = binaryData.size()](ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); peer->send(Blob::deserialize(url, type, size, { })); }); Ref<Bridge> protectedThis(*this); waitForMethodCompletion(); return m_workerClientWrapper->sendRequestResult(); }
unsigned WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() { if (!m_peer) return 0; setMethodNotCompleted(); m_loaderProxy.postTaskToLoader([peer = m_peer](ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); peer->bufferedAmount(); }); Ref<Bridge> protectedThis(*this); waitForMethodCompletion(); return m_workerClientWrapper->bufferedAmount(); }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message) { if (!m_peer) return ThreadableWebSocketChannel::SendFail; setMethodNotCompleted(); m_loaderProxy.postTaskToLoader([peer = m_peer, message = message.isolatedCopy()](ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); peer->send(message); }); Ref<Bridge> protectedThis(*this); waitForMethodCompletion(); return m_workerClientWrapper->sendRequestResult(); }
void WorkerThreadableWebSocketChannel::Bridge::initialize() { ASSERT(!m_peer); setMethodNotCompleted(); Ref<Bridge> protect(*this); WorkerLoaderProxy* loaderProxy = &m_loaderProxy; RefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper = m_workerClientWrapper; StringCapture capturedTaskMode(m_taskMode); m_loaderProxy.postTaskToLoader([loaderProxy, workerClientWrapper, capturedTaskMode] (ScriptExecutionContext& context) { mainThreadInitialize(context, loaderProxy, workerClientWrapper, capturedTaskMode.string()); }); waitForMethodCompletion(); // m_peer may be null when the nested runloop exited before a peer has created. m_peer = m_workerClientWrapper->peer(); if (!m_peer) m_workerClientWrapper->setFailedWebSocketChannelCreation(); }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message) { if (!m_workerClientWrapper || !m_peer) return ThreadableWebSocketChannel::SendFail; setMethodNotCompleted(); Peer* peer = m_peer; StringCapture capturedMessage(message); m_loaderProxy.postTaskToLoader([peer, capturedMessage] (ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); peer->send(capturedMessage.string()); }); Ref<Bridge> protect(*this); waitForMethodCompletion(); ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get(); if (!clientWrapper) return ThreadableWebSocketChannel::SendFail; return clientWrapper->sendRequestResult(); }
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) { if (!m_peer) return ThreadableWebSocketChannel::SendFail; // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. Vector<char> data(byteLength); if (binaryData.byteLength()) memcpy(data.data(), static_cast<const char*>(binaryData.data()) + byteOffset, byteLength); setMethodNotCompleted(); m_loaderProxy.postTaskToLoader([peer = m_peer, data = WTFMove(data)](ScriptExecutionContext& context) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context.isDocument()); ASSERT(peer); auto arrayBuffer = ArrayBuffer::create(data.data(), data.size()); peer->send(arrayBuffer); }); Ref<Bridge> protectedThis(*this); waitForMethodCompletion(); return m_workerClientWrapper->sendRequestResult(); }