forked from mirrors/gecko-dev
Backed out 2 changesets (bug 1830096) for xpc failures on test_webtransport_simple.js. CLOSED TREE
Backed out changeset 54cc048fd39a (bug 1830096) Backed out changeset 7337707e8b32 (bug 1830096)
This commit is contained in:
parent
f1a92cac23
commit
82030e5f73
6 changed files with 66 additions and 153 deletions
|
|
@ -333,8 +333,6 @@ void WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
|
|||
NS_ConvertUTF16toUTF8(aURL).get()));
|
||||
|
||||
// https://w3c.github.io/webtransport/#webtransport-constructor Spec 5.2
|
||||
mChild = child;
|
||||
mDatagrams->SetChild(child);
|
||||
backgroundChild
|
||||
->SendCreateWebTransportParent(aURL, principal, ipcClientInfo, dedicated,
|
||||
requireUnreliable,
|
||||
|
|
@ -342,9 +340,9 @@ void WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
|
|||
// XXX serverCertHashes,
|
||||
std::move(parentEndpoint))
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr{this}](
|
||||
PBackgroundChild::CreateWebTransportParentPromise::
|
||||
ResolveOrRejectValue&& aResult) {
|
||||
[self = RefPtr{this},
|
||||
child](PBackgroundChild::CreateWebTransportParentPromise::
|
||||
ResolveOrRejectValue&& aResult) {
|
||||
// aResult is a std::tuple<nsresult, uint8_t>
|
||||
// TODO: is there a better/more-spec-compliant error in the
|
||||
// reject case? Which begs the question, why would we get a
|
||||
|
|
@ -355,20 +353,21 @@ void WebTransport::Init(const GlobalObject& aGlobal, const nsAString& aURL,
|
|||
LOG(("isreject: %d nsresult 0x%x", aResult.IsReject(),
|
||||
(uint32_t)rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
self->RejectWaitingConnection(rv);
|
||||
self->RejectWaitingConnection(rv, child);
|
||||
} else {
|
||||
// This will process anything waiting for the connection to
|
||||
// complete;
|
||||
|
||||
self->ResolveWaitingConnection(
|
||||
static_cast<WebTransportReliabilityMode>(
|
||||
std::get<1>(aResult.ResolveValue())));
|
||||
std::get<1>(aResult.ResolveValue())),
|
||||
child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void WebTransport::ResolveWaitingConnection(
|
||||
WebTransportReliabilityMode aReliability) {
|
||||
WebTransportReliabilityMode aReliability, WebTransportChild* aChild) {
|
||||
LOG(("Resolved Connection %p, reliability = %u", this,
|
||||
(unsigned)aReliability));
|
||||
// https://w3c.github.io/webtransport/#webtransport-constructor
|
||||
|
|
@ -381,6 +380,8 @@ void WebTransport::ResolveWaitingConnection(
|
|||
return;
|
||||
}
|
||||
|
||||
mChild = aChild;
|
||||
mDatagrams->SetChild(aChild);
|
||||
// Step 17.2: Set transport.[[State]] to "connected".
|
||||
mState = WebTransportState::CONNECTED;
|
||||
// Step 17.3: Set transport.[[Session]] to session.
|
||||
|
|
@ -391,7 +392,8 @@ void WebTransport::ResolveWaitingConnection(
|
|||
mReady->MaybeResolveWithUndefined();
|
||||
}
|
||||
|
||||
void WebTransport::RejectWaitingConnection(nsresult aRv) {
|
||||
void WebTransport::RejectWaitingConnection(nsresult aRv,
|
||||
WebTransportChild* aChild) {
|
||||
LOG(("Rejected connection %p %x", this, (uint32_t)aRv));
|
||||
// https://w3c.github.io/webtransport/#initialize-webtransport-over-http
|
||||
|
||||
|
|
@ -406,8 +408,7 @@ void WebTransport::RejectWaitingConnection(nsresult aRv) {
|
|||
// these steps.
|
||||
if (mState == WebTransportState::CLOSED ||
|
||||
mState == WebTransportState::FAILED) {
|
||||
mChild->Shutdown(true);
|
||||
mChild = nullptr;
|
||||
aChild->Shutdown(true);
|
||||
// Cleanup should have been called, which means Ready has been
|
||||
// rejected and pulls resolved
|
||||
return;
|
||||
|
|
@ -420,8 +421,8 @@ void WebTransport::RejectWaitingConnection(nsresult aRv) {
|
|||
// Step 14.3: Cleanup transport with error.
|
||||
Cleanup(error, nullptr, IgnoreErrors());
|
||||
|
||||
mChild->Shutdown(true);
|
||||
mChild = nullptr;
|
||||
// We never set mChild, but we need to prepare it to die
|
||||
aChild->Shutdown(true);
|
||||
}
|
||||
|
||||
bool WebTransport::ParseURL(const nsAString& aURL) const {
|
||||
|
|
@ -513,8 +514,7 @@ void WebTransport::Close(const WebTransportCloseInfo& aOptions,
|
|||
// Step 3.2: Cleanup transport with error.
|
||||
Cleanup(error, nullptr, aRv);
|
||||
// Step 3.3: Abort these steps.
|
||||
mChild->Shutdown(true);
|
||||
mChild = nullptr;
|
||||
MOZ_ASSERT(!mChild);
|
||||
return;
|
||||
}
|
||||
LOG(("Sending Close"));
|
||||
|
|
@ -596,10 +596,6 @@ already_AddRefed<Promise> WebTransport::CreateBidirectionalStream(
|
|||
LOG(("CreateBidirectionalStream response"));
|
||||
// Step 5.2.1: If transport.[[State]] is "closed" or "failed",
|
||||
// reject p with an InvalidStateError and abort these steps.
|
||||
if (BidirectionalStreamResponse::Tnsresult == aPipes.type()) {
|
||||
promise->MaybeReject(aPipes.get_nsresult());
|
||||
return;
|
||||
}
|
||||
if (self->mState == WebTransportState::CLOSED ||
|
||||
self->mState == WebTransportState::FAILED) {
|
||||
promise->MaybeRejectWithInvalidStateError(
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ class WebTransport final : public nsISupports, public nsWrapperCache {
|
|||
const nsAString& aUrl,
|
||||
const WebTransportOptions& aOptions,
|
||||
ErrorResult& aError);
|
||||
void ResolveWaitingConnection(WebTransportReliabilityMode aReliability);
|
||||
void RejectWaitingConnection(nsresult aRv);
|
||||
void ResolveWaitingConnection(WebTransportReliabilityMode aReliability,
|
||||
WebTransportChild* aChild);
|
||||
void RejectWaitingConnection(nsresult aRv, WebTransportChild* aChild);
|
||||
bool ParseURL(const nsAString& aURL) const;
|
||||
// this calls CloseNative(), which doesn't actually run script. See bug
|
||||
// 1810942
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ JS_HAZ_CAN_RUN_SCRIPT NS_IMETHODIMP ReceiveStream::OnError(uint8_t aError) {
|
|||
nsresult rv = aError == nsIWebTransport::INVALID_STATE_ERROR
|
||||
? NS_ERROR_DOM_INVALID_STATE_ERR
|
||||
: NS_ERROR_FAILURE;
|
||||
LOG(("CreateStream OnError: %u", aError));
|
||||
if (mUniResolver) {
|
||||
mUniResolver(nullptr);
|
||||
} else if (mBiResolver) {
|
||||
|
|
|
|||
|
|
@ -317,67 +317,18 @@ class WebTransportStreamCallbackWrapper final {
|
|||
};
|
||||
|
||||
void WebTransportSessionProxy::CreateStreamInternal(
|
||||
nsIWebTransportStreamCallback* callback, bool aBidi) {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
LOG(
|
||||
("WebTransportSessionProxy::CreateStreamInternal %p "
|
||||
"mState=%d, bidi=%d",
|
||||
this, mState, aBidi));
|
||||
switch (mState) {
|
||||
case WebTransportSessionProxyState::INIT:
|
||||
case WebTransportSessionProxyState::NEGOTIATING:
|
||||
case WebTransportSessionProxyState::NEGOTIATING_SUCCEEDED:
|
||||
case WebTransportSessionProxyState::ACTIVE: {
|
||||
RefPtr<WebTransportStreamCallbackWrapper> wrapper =
|
||||
new WebTransportStreamCallbackWrapper(callback, aBidi);
|
||||
if (mState == WebTransportSessionProxyState::ACTIVE &&
|
||||
mWebTransportSession) {
|
||||
DoCreateStream(wrapper, mWebTransportSession, aBidi);
|
||||
} else {
|
||||
LOG(
|
||||
("WebTransportSessionProxy::CreateStreamInternal %p "
|
||||
" queue create stream event",
|
||||
this));
|
||||
auto task = [self = RefPtr{this}, wrapper{std::move(wrapper)},
|
||||
bidi(aBidi)](nsresult aStatus) {
|
||||
if (NS_FAILED(aStatus)) {
|
||||
wrapper->CallOnError(aStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
self->DoCreateStream(wrapper, nullptr, bidi);
|
||||
};
|
||||
mPendingCreateStreamEvents.AppendElement(std::move(task));
|
||||
}
|
||||
} break;
|
||||
case WebTransportSessionProxyState::SESSION_CLOSE_PENDING:
|
||||
case WebTransportSessionProxyState::CLOSE_CALLBACK_PENDING:
|
||||
case WebTransportSessionProxyState::DONE: {
|
||||
nsCOMPtr<nsIWebTransportStreamCallback> cb(callback);
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::CreateOutgoingUnidirectionalStream",
|
||||
[cb{std::move(cb)}]() {
|
||||
cb->OnError(nsIWebTransport::INVALID_STATE_ERROR);
|
||||
}));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void WebTransportSessionProxy::DoCreateStream(
|
||||
WebTransportStreamCallbackWrapper* aCallback,
|
||||
Http3WebTransportSession* aSession, bool aBidi) {
|
||||
WebTransportStreamCallbackWrapper* aCallback, bool aBidi) {
|
||||
if (!OnSocketThread()) {
|
||||
RefPtr<WebTransportSessionProxy> self(this);
|
||||
RefPtr<WebTransportStreamCallbackWrapper> wrapper(aCallback);
|
||||
Unused << gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::DoCreateStream",
|
||||
"WebTransportSessionProxy::CreateStreamInternal",
|
||||
[self{std::move(self)}, wrapper{std::move(wrapper)}, bidi(aBidi)]() {
|
||||
self->DoCreateStream(wrapper, nullptr, bidi);
|
||||
self->CreateStreamInternal(wrapper, bidi);
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(("WebTransportSessionProxy::DoCreateStream %p bidi=%d", this, aBidi));
|
||||
RefPtr<WebTransportStreamCallbackWrapper> wrapper(aCallback);
|
||||
auto callback =
|
||||
[wrapper{std::move(wrapper)}](
|
||||
|
|
@ -393,8 +344,8 @@ void WebTransportSessionProxy::DoCreateStream(
|
|||
wrapper->CallOnStreamReady(streamProxy);
|
||||
};
|
||||
|
||||
RefPtr<Http3WebTransportSession> session = aSession;
|
||||
if (!aSession) {
|
||||
RefPtr<Http3WebTransportSession> session;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
session = mWebTransportSession;
|
||||
}
|
||||
|
|
@ -419,8 +370,23 @@ WebTransportSessionProxy::CreateOutgoingUnidirectionalStream(
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
CreateStreamInternal(callback, false);
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mState != WebTransportSessionProxyState::ACTIVE ||
|
||||
!mWebTransportSession) {
|
||||
nsCOMPtr<nsIWebTransportStreamCallback> cb(callback);
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::CreateOutgoingUnidirectionalStream",
|
||||
[cb{std::move(cb)}]() {
|
||||
cb->OnError(nsIWebTransport::INVALID_STATE_ERROR);
|
||||
}));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<WebTransportStreamCallbackWrapper> wrapper =
|
||||
new WebTransportStreamCallbackWrapper(callback, false);
|
||||
CreateStreamInternal(wrapper, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -431,8 +397,23 @@ WebTransportSessionProxy::CreateOutgoingBidirectionalStream(
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
CreateStreamInternal(callback, true);
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mState != WebTransportSessionProxyState::ACTIVE ||
|
||||
!mWebTransportSession) {
|
||||
nsCOMPtr<nsIWebTransportStreamCallback> cb(callback);
|
||||
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::CreateOutgoingBidirectionalStream",
|
||||
[cb{std::move(cb)}]() {
|
||||
cb->OnError(nsIWebTransport::INVALID_STATE_ERROR);
|
||||
}));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<WebTransportStreamCallbackWrapper> wrapper =
|
||||
new WebTransportStreamCallbackWrapper(callback, true);
|
||||
CreateStreamInternal(wrapper, true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -580,8 +561,6 @@ WebTransportSessionProxy::OnStopRequest(nsIRequest* aRequest,
|
|||
uint32_t closeStatus = 0;
|
||||
uint64_t sessionId;
|
||||
bool succeeded = false;
|
||||
nsTArray<std::function<void()>> pendingEvents;
|
||||
nsTArray<std::function<void(nsresult)>> pendingCreateStreamEvents;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
switch (mState) {
|
||||
|
|
@ -618,25 +597,16 @@ WebTransportSessionProxy::OnStopRequest(nsIRequest* aRequest,
|
|||
case WebTransportSessionProxyState::DONE:
|
||||
break;
|
||||
}
|
||||
pendingEvents = std::move(mPendingEvents);
|
||||
pendingCreateStreamEvents = std::move(mPendingCreateStreamEvents);
|
||||
mStopRequestCalled = true;
|
||||
}
|
||||
|
||||
if (!pendingCreateStreamEvents.IsEmpty()) {
|
||||
Unused << gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::DispatchPendingCreateStreamEvents",
|
||||
[pendingCreateStreamEvents = std::move(pendingCreateStreamEvents),
|
||||
status(aStatus)]() {
|
||||
for (const auto& event : pendingCreateStreamEvents) {
|
||||
event(status);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
if (succeeded) {
|
||||
listener->OnSessionReady(sessionId);
|
||||
nsTArray<std::function<void()>> pendingEvents;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
pendingEvents = std::move(mPendingEvents);
|
||||
mStopRequestCalled = true;
|
||||
}
|
||||
if (!pendingEvents.IsEmpty()) {
|
||||
Unused << gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::DispatchPendingEvents",
|
||||
|
|
|
|||
|
|
@ -158,10 +158,8 @@ class WebTransportSessionProxy final : public nsIWebTransport,
|
|||
WebTransportSessionProxyState mState MOZ_GUARDED_BY(mMutex) =
|
||||
WebTransportSessionProxyState::INIT;
|
||||
void ChangeState(WebTransportSessionProxyState newState);
|
||||
void CreateStreamInternal(nsIWebTransportStreamCallback* callback,
|
||||
void CreateStreamInternal(WebTransportStreamCallbackWrapper* aCallback,
|
||||
bool aBidi);
|
||||
void DoCreateStream(WebTransportStreamCallbackWrapper* aCallback,
|
||||
Http3WebTransportSession* aSession, bool aBidi);
|
||||
void SendDatagramInternal(const RefPtr<Http3WebTransportSession>& aSession,
|
||||
nsTArray<uint8_t>&& aData, uint64_t aTrackingId);
|
||||
void NotifyDatagramReceived(nsTArray<uint8_t>&& aData);
|
||||
|
|
@ -182,8 +180,6 @@ class WebTransportSessionProxy final : public nsIWebTransport,
|
|||
// This is used to store events happened before OnSessionReady.
|
||||
// Note that these events will be dispatched to the socket thread.
|
||||
nsTArray<std::function<void()>> mPendingEvents MOZ_GUARDED_BY(mMutex);
|
||||
nsTArray<std::function<void(nsresult)>> mPendingCreateStreamEvents
|
||||
MOZ_GUARDED_BY(mMutex);
|
||||
nsCOMPtr<nsIEventTarget> mTarget MOZ_GUARDED_BY(mMutex);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,27 +21,7 @@ promise_test(async t => {
|
|||
|
||||
// Check that the message from the readable end matches the writable end.
|
||||
assert_equals(reply, 'Hello World');
|
||||
}, 'WebTransport client should be able to create and handle a bidirectional stream');
|
||||
|
||||
promise_test(async t => {
|
||||
// Establish a WebTransport session.
|
||||
const wt = new WebTransport(webtransport_url('echo.py'));
|
||||
|
||||
// Create a bidirectional stream.
|
||||
const bidi_stream = await wt.createBidirectionalStream();
|
||||
|
||||
// Write a message to the writable end, and close it.
|
||||
const writer = bidi_stream.writable.getWriter();
|
||||
const encoder = new TextEncoder();
|
||||
await writer.write(encoder.encode('Hello World'));
|
||||
await writer.close();
|
||||
|
||||
// Read the data on the readable end.
|
||||
const reply = await read_stream_as_string(bidi_stream.readable);
|
||||
|
||||
// Check that the message from the readable end matches the writable end.
|
||||
assert_equals(reply, 'Hello World');
|
||||
}, 'WebTransport client should be able to create and handle a bidirectional stream without waiting for ready');
|
||||
}, 'WebTransport server should be able to create and handle a bidirectional stream');
|
||||
|
||||
promise_test(async t => {
|
||||
// Establish a WebTransport session.
|
||||
|
|
@ -96,36 +76,7 @@ promise_test(async t => {
|
|||
// Make sure the message on the writable and readable ends of the streams
|
||||
// match.
|
||||
assert_equals(reply, 'Hello World');
|
||||
}, 'WebTransport client should be able to create, accept, and handle a unidirectional stream');
|
||||
|
||||
promise_test(async t => {
|
||||
// Establish a WebTransport session.
|
||||
const wt = new WebTransport(webtransport_url('echo.py'));
|
||||
|
||||
// Create a unidirectional stream.
|
||||
const writable = await wt.createUnidirectionalStream();
|
||||
|
||||
// Write a message to the writable end, and close it.
|
||||
const encoder = new TextEncoderStream();
|
||||
encoder.readable.pipeTo(writable);
|
||||
const writer = encoder.writable.getWriter();
|
||||
await writer.write('Hello World');
|
||||
await writer.close();
|
||||
|
||||
// The echo handler creates a new unidirectional stream to echo back data from
|
||||
// the server to client. Accept the unidirectional stream.
|
||||
const readable = wt.incomingUnidirectionalStreams;
|
||||
const stream_reader = readable.getReader();
|
||||
const { value: recv_stream } = await stream_reader.read();
|
||||
stream_reader.releaseLock();
|
||||
|
||||
// Read the data on the readable end.
|
||||
const reply = await read_stream_as_string(recv_stream);
|
||||
|
||||
// Make sure the message on the writable and readable ends of the streams
|
||||
// match.
|
||||
assert_equals(reply, 'Hello World');
|
||||
}, 'WebTransport client should be able to create, accept, and handle a unidirectional stream without waiting for ready');
|
||||
}, 'WebTransport server should be able to create, accept, and handle a unidirectional stream');
|
||||
|
||||
promise_test(async t => {
|
||||
// Establish a WebTransport session.
|
||||
|
|
|
|||
Loading…
Reference in a new issue