зеркало из https://github.com/mozilla/gecko-dev.git
201 строка
6.6 KiB
C++
201 строка
6.6 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_dom_serviceworkerop_h__
|
|
#define mozilla_dom_serviceworkerop_h__
|
|
|
|
#include <functional>
|
|
|
|
#include "mozilla/dom/ServiceWorkerOpPromise.h"
|
|
#include "nsISupportsImpl.h"
|
|
|
|
#include "ServiceWorkerEvents.h"
|
|
#include "ServiceWorkerOpPromise.h"
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/Maybe.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "mozilla/TimeStamp.h"
|
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
|
#include "mozilla/dom/RemoteWorkerChild.h"
|
|
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
|
#include "mozilla/dom/WorkerRunnable.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
class FetchEventOpProxyChild;
|
|
|
|
class ServiceWorkerOp : public RemoteWorkerChild::Op {
|
|
public:
|
|
// `aCallback` will be called when the operation completes or is canceled.
|
|
static already_AddRefed<ServiceWorkerOp> Create(
|
|
ServiceWorkerOpArgs&& aArgs,
|
|
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
|
|
|
|
ServiceWorkerOp(
|
|
ServiceWorkerOpArgs&& aArgs,
|
|
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
|
|
|
|
ServiceWorkerOp(const ServiceWorkerOp&) = delete;
|
|
|
|
ServiceWorkerOp& operator=(const ServiceWorkerOp&) = delete;
|
|
|
|
ServiceWorkerOp(ServiceWorkerOp&&) = default;
|
|
|
|
ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default;
|
|
|
|
// Returns `true` if the operation has started and `false` otherwise.
|
|
bool MaybeStart(RemoteWorkerChild* aOwner,
|
|
RemoteWorkerChild::State& aState) final;
|
|
|
|
void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) final;
|
|
|
|
void Cancel() final;
|
|
|
|
protected:
|
|
~ServiceWorkerOp();
|
|
|
|
bool Started() const;
|
|
|
|
bool IsTerminationOp() const;
|
|
|
|
// Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
|
|
virtual RefPtr<WorkerThreadRunnable> GetRunnable(
|
|
WorkerPrivate* aWorkerPrivate);
|
|
|
|
// Overridden by ServiceWorkerOp subclasses, it should return true when
|
|
// the ServiceWorkerOp was executed successfully (and false if it did fail).
|
|
// Content throwing an exception during event dispatch is still considered
|
|
// success.
|
|
virtual bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
|
|
|
|
// Override to reject any additional MozPromises that subclasses may contain.
|
|
virtual void RejectAll(nsresult aStatus);
|
|
|
|
ServiceWorkerOpArgs mArgs;
|
|
|
|
// Subclasses must settle this promise when appropriate.
|
|
MozPromiseHolder<ServiceWorkerOpPromise> mPromiseHolder;
|
|
|
|
private:
|
|
class ServiceWorkerOpRunnable;
|
|
|
|
bool mStarted = false;
|
|
};
|
|
|
|
class ExtendableEventOp : public ServiceWorkerOp,
|
|
public ExtendableEventCallback {
|
|
using ServiceWorkerOp::ServiceWorkerOp;
|
|
|
|
protected:
|
|
~ExtendableEventOp() = default;
|
|
|
|
void FinishedWithResult(ExtendableEventResult aResult) override;
|
|
};
|
|
|
|
class FetchEventOp final : public ExtendableEventOp,
|
|
public PromiseNativeHandler {
|
|
using ExtendableEventOp::ExtendableEventOp;
|
|
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
/**
|
|
* This must be called once and only once before the first call to
|
|
* `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
|
|
* `ReportCanceled().`
|
|
*/
|
|
void SetActor(RefPtr<FetchEventOpProxyChild> aActor);
|
|
|
|
void RevokeActor(FetchEventOpProxyChild* aActor);
|
|
|
|
// This must be called at most once before the first call to `MaybeStart().`
|
|
RefPtr<FetchEventRespondWithPromise> GetRespondWithPromise();
|
|
|
|
// This must be called when `FetchEvent::RespondWith()` is called.
|
|
void RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
|
|
uint32_t aRespondWithLineNumber,
|
|
uint32_t aRespondWithColumnNumber);
|
|
|
|
void ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
|
|
uint32_t aPreventDefaultLineNumber,
|
|
uint32_t aPreventDefaultColumnNumber);
|
|
|
|
private:
|
|
class AutoCancel;
|
|
|
|
~FetchEventOp();
|
|
|
|
bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
|
|
|
|
void RejectAll(nsresult aStatus) override;
|
|
|
|
void FinishedWithResult(ExtendableEventResult aResult) override;
|
|
|
|
/**
|
|
* `{Resolved,Reject}Callback()` are use to handle the
|
|
* `FetchEvent::RespondWith()` promise.
|
|
*/
|
|
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
|
ErrorResult& aRv) override;
|
|
|
|
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
|
ErrorResult& aRv) override;
|
|
|
|
void MaybeFinished();
|
|
|
|
// Requires mRespondWithClosure to be non-empty.
|
|
void AsyncLog(const nsCString& aMessageName, nsTArray<nsString> aParams);
|
|
|
|
void AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
|
|
uint32_t aColumnNumber, const nsCString& aMessageName,
|
|
nsTArray<nsString> aParams);
|
|
|
|
void GetRequestURL(nsAString& aOutRequestURL);
|
|
|
|
// A failure code means that the dispatch failed.
|
|
nsresult DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
|
|
|
|
// Worker Launcher thread only. Used for `AsyncLog().`
|
|
RefPtr<FetchEventOpProxyChild> mActor;
|
|
|
|
/**
|
|
* Created on the Worker Launcher thread and settled on the worker thread.
|
|
* If this isn't settled before `mPromiseHolder` (which it should be),
|
|
* `FetchEventOpChild` will cancel the intercepted network request.
|
|
*/
|
|
MozPromiseHolder<FetchEventRespondWithPromise> mRespondWithPromiseHolder;
|
|
|
|
// Worker thread only.
|
|
Maybe<ExtendableEventResult> mResult;
|
|
bool mPostDispatchChecksDone = false;
|
|
|
|
// Worker thread only; set when `FetchEvent::RespondWith()` is called.
|
|
Maybe<FetchEventRespondWithClosure> mRespondWithClosure;
|
|
|
|
// Must be set to `nullptr` on the worker thread because `Promise`'s
|
|
// destructor must be called on the worker thread.
|
|
RefPtr<Promise> mHandled;
|
|
|
|
// Must be set to `nullptr` on the worker thread because `Promise`'s
|
|
// destructor must be called on the worker thread.
|
|
RefPtr<Promise> mPreloadResponse;
|
|
|
|
// Holds the callback that resolves mPreloadResponse.
|
|
MozPromiseRequestHolder<FetchEventPreloadResponseAvailablePromise>
|
|
mPreloadResponseAvailablePromiseRequestHolder;
|
|
MozPromiseRequestHolder<FetchEventPreloadResponseTimingPromise>
|
|
mPreloadResponseTimingPromiseRequestHolder;
|
|
MozPromiseRequestHolder<FetchEventPreloadResponseEndPromise>
|
|
mPreloadResponseEndPromiseRequestHolder;
|
|
|
|
TimeStamp mFetchHandlerStart;
|
|
TimeStamp mFetchHandlerFinish;
|
|
};
|
|
|
|
} // namespace mozilla::dom
|
|
|
|
#endif // mozilla_dom_serviceworkerop_h__
|