/* -*- 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_serviceworkerjob_h #define mozilla_dom_serviceworkerjob_h #include "nsCOMPtr.h" #include "nsString.h" #include "nsTArray.h" class nsIPrincipal; namespace mozilla { class ErrorResult; namespace dom { class ServiceWorkerJob { public: // Implement this interface to receive notification when a job completes. class Callback { public: // Called once when the job completes. If the job is started, then this // will be called. If a job is never executed due to browser shutdown, // then this method will never be called. This method is always called // on the main thread asynchronously after Start() completes. virtual void JobFinished(ServiceWorkerJob* aJob, ErrorResult& aStatus) = 0; NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING }; enum class Type { Register, Update, Unregister }; enum class State { Initial, Started, Finished }; Type GetType() const; State GetState() const; // Determine if the job has been canceled. This does not change the // current State, but indicates that the job should progress to Finished // as soon as possible. bool Canceled() const; // Determine if the result callbacks have already been called. This is // equivalent to the spec checked to see if the job promise has settled. bool ResultCallbacksInvoked() const; bool IsEquivalentTo(ServiceWorkerJob* aJob) const; // Add a callback that will be invoked when the job's result is available. // Some job types will invoke this before the job is actually finished. // If an early callback does not occur, then it will be called automatically // when Finish() is called. These callbacks will be invoked while the job // state is Started. void AppendResultCallback(Callback* aCallback); // This takes ownership of any result callbacks associated with the given job // and then appends them to this job's callback list. void StealResultCallbacksFrom(ServiceWorkerJob* aJob); // Start the job. All work will be performed asynchronously on // the main thread. The Finish() method must be called exactly // once after this point. A final callback must be provided. It // will be invoked after all other callbacks have been processed. void Start(Callback* aFinalCallback); // Set an internal flag indicating that a started job should finish as // soon as possible. void Cancel(); protected: ServiceWorkerJob(Type aType, nsIPrincipal* aPrincipal, const nsACString& aScope, const nsACString& aScriptSpec); virtual ~ServiceWorkerJob(); // Invoke the result callbacks immediately. The job must be in the // Started state. The callbacks are cleared after being invoked, // so subsequent method calls have no effect. void InvokeResultCallbacks(ErrorResult& aRv); // Convenience method that converts to ErrorResult and calls real method. void InvokeResultCallbacks(nsresult aRv); // Indicate that the job has completed. The must be called exactly // once after Start() has initiated job execution. It may not be // called until Start() has returned. void Finish(ErrorResult& aRv); // Convenience method that converts to ErrorResult and calls real method. void Finish(nsresult aRv); // Specific job types should define AsyncExecute to begin their work. // All errors and successes must result in Finish() being called. virtual void AsyncExecute() = 0; const Type mType; nsCOMPtr mPrincipal; const nsCString mScope; const nsCString mScriptSpec; private: RefPtr mFinalCallback; nsTArray> mResultCallbackList; State mState; bool mCanceled; bool mResultCallbacksInvoked; public: NS_INLINE_DECL_REFCOUNTING(ServiceWorkerJob) }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_serviceworkerjob_h