LCOV - code coverage report
Current view: top level - dom/workers - ServiceWorkerPrivate.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 3 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_workers_serviceworkerprivate_h
       8             : #define mozilla_dom_workers_serviceworkerprivate_h
       9             : 
      10             : #include "nsCOMPtr.h"
      11             : 
      12             : #include "WorkerPrivate.h"
      13             : 
      14             : #define NOTIFICATION_CLICK_EVENT_NAME "notificationclick"
      15             : #define NOTIFICATION_CLOSE_EVENT_NAME "notificationclose"
      16             : 
      17             : class nsIInterceptedChannel;
      18             : 
      19             : namespace mozilla {
      20             : namespace dom {
      21             : namespace workers {
      22             : 
      23             : class ServiceWorkerInfo;
      24             : class ServiceWorkerRegistrationInfo;
      25             : class KeepAliveToken;
      26             : 
      27           0 : class LifeCycleEventCallback : public Runnable
      28             : {
      29             : public:
      30           0 :   LifeCycleEventCallback() : Runnable("dom::workers::LifeCycleEventCallback") {}
      31             : 
      32             :   // Called on the worker thread.
      33             :   virtual void
      34             :   SetResult(bool aResult) = 0;
      35             : };
      36             : 
      37             : // ServiceWorkerPrivate is a wrapper for managing the on-demand aspect of
      38             : // service workers. It handles all event dispatching to the worker and ensures
      39             : // the worker thread is running when needed.
      40             : //
      41             : // Lifetime management: To spin up the worker thread we own a |WorkerPrivate|
      42             : // object which can be cancelled if no events are received for a certain
      43             : // amount of time. The worker is kept alive by holding a |KeepAliveToken|
      44             : // reference.
      45             : //
      46             : // Extendable events hold tokens for the duration of their handler execution
      47             : // and until their waitUntil promise is resolved, while ServiceWorkerPrivate
      48             : // will hold a token for |dom.serviceWorkers.idle_timeout| seconds after each
      49             : // new event.
      50             : //
      51             : // Note: All timer events must be handled on the main thread because the
      52             : // worker may block indefinitely the worker thread (e. g. infinite loop in the
      53             : // script).
      54             : //
      55             : // There are 3 cases where we may ignore keep alive tokens:
      56             : // 1. When ServiceWorkerPrivate's token expired, if there are still waitUntil
      57             : // handlers holding tokens, we wait another |dom.serviceWorkers.idle_extended_timeout|
      58             : // seconds before forcibly terminating the worker.
      59             : // 2. If the worker stopped controlling documents and it is not handling push
      60             : // events.
      61             : // 3. The content process is shutting down.
      62             : //
      63             : // Adding an API function for a new event requires calling |SpawnWorkerIfNeeded|
      64             : // with an appropriate reason before any runnable is dispatched to the worker.
      65             : // If the event is extendable then the runnable should inherit
      66             : // ExtendableEventWorkerRunnable.
      67             : class ServiceWorkerPrivate final
      68             : {
      69             :   friend class KeepAliveToken;
      70             : 
      71             : public:
      72             :   NS_IMETHOD_(MozExternalRefCountType) AddRef();
      73             :   NS_IMETHOD_(MozExternalRefCountType) Release();
      74           0 :   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ServiceWorkerPrivate)
      75             : 
      76             :   typedef mozilla::FalseType HasThreadSafeRefCnt;
      77             : 
      78             : protected:
      79             :   nsCycleCollectingAutoRefCnt mRefCnt;
      80             :   NS_DECL_OWNINGTHREAD
      81             : 
      82             : public:
      83             :   explicit ServiceWorkerPrivate(ServiceWorkerInfo* aInfo);
      84             : 
      85             :   nsresult
      86             :   SendMessageEvent(JSContext* aCx, JS::Handle<JS::Value> aMessage,
      87             :                    const Sequence<JSObject*>& aTransferable,
      88             :                    UniquePtr<ServiceWorkerClientInfo>&& aClientInfo);
      89             : 
      90             :   // This is used to validate the worker script and continue the installation
      91             :   // process.
      92             :   nsresult
      93             :   CheckScriptEvaluation(LifeCycleEventCallback* aCallback);
      94             : 
      95             :   nsresult
      96             :   SendLifeCycleEvent(const nsAString& aEventType,
      97             :                      LifeCycleEventCallback* aCallback,
      98             :                      nsIRunnable* aLoadFailure);
      99             : 
     100             :   nsresult
     101             :   SendPushEvent(const nsAString& aMessageId,
     102             :                 const Maybe<nsTArray<uint8_t>>& aData,
     103             :                 ServiceWorkerRegistrationInfo* aRegistration);
     104             : 
     105             :   nsresult
     106             :   SendPushSubscriptionChangeEvent();
     107             : 
     108             :   nsresult
     109             :   SendNotificationEvent(const nsAString& aEventName,
     110             :                         const nsAString& aID,
     111             :                         const nsAString& aTitle,
     112             :                         const nsAString& aDir,
     113             :                         const nsAString& aLang,
     114             :                         const nsAString& aBody,
     115             :                         const nsAString& aTag,
     116             :                         const nsAString& aIcon,
     117             :                         const nsAString& aData,
     118             :                         const nsAString& aBehavior,
     119             :                         const nsAString& aScope);
     120             : 
     121             :   nsresult
     122             :   SendFetchEvent(nsIInterceptedChannel* aChannel,
     123             :                  nsILoadGroup* aLoadGroup,
     124             :                  const nsAString& aDocumentId,
     125             :                  bool aIsReload);
     126             : 
     127             :   void
     128             :   StoreISupports(nsISupports* aSupports);
     129             : 
     130             :   void
     131             :   RemoveISupports(nsISupports* aSupports);
     132             : 
     133             :   // This will terminate the current running worker thread and drop the
     134             :   // workerPrivate reference.
     135             :   // Called by ServiceWorkerInfo when [[Clear Registration]] is invoked
     136             :   // or whenever the spec mandates that we terminate the worker.
     137             :   // This is a no-op if the worker has already been stopped.
     138             :   void
     139             :   TerminateWorker();
     140             : 
     141             :   void
     142             :   NoteDeadServiceWorkerInfo();
     143             : 
     144             :   void
     145             :   NoteStoppedControllingDocuments();
     146             : 
     147             :   void
     148             :   Activated();
     149             : 
     150             :   nsresult
     151             :   GetDebugger(nsIWorkerDebugger** aResult);
     152             : 
     153             :   nsresult
     154             :   AttachDebugger();
     155             : 
     156             :   nsresult
     157             :   DetachDebugger();
     158             : 
     159             :   bool
     160             :   IsIdle() const;
     161             : 
     162             :   void
     163             :   SetHandlesFetch(bool aValue);
     164             : 
     165             : private:
     166             :   enum WakeUpReason {
     167             :     FetchEvent = 0,
     168             :     PushEvent,
     169             :     PushSubscriptionChangeEvent,
     170             :     MessageEvent,
     171             :     NotificationClickEvent,
     172             :     NotificationCloseEvent,
     173             :     LifeCycleEvent,
     174             :     AttachEvent
     175             :   };
     176             : 
     177             :   // Timer callbacks
     178             :   void
     179             :   NoteIdleWorkerCallback(nsITimer* aTimer);
     180             : 
     181             :   void
     182             :   TerminateWorkerCallback(nsITimer* aTimer);
     183             : 
     184             :   void
     185             :   RenewKeepAliveToken(WakeUpReason aWhy);
     186             : 
     187             :   void
     188             :   ResetIdleTimeout();
     189             : 
     190             :   void
     191             :   AddToken();
     192             : 
     193             :   void
     194             :   ReleaseToken();
     195             : 
     196             :   // |aLoadFailedRunnable| is a runnable dispatched to the main thread
     197             :   // if the script loader failed for some reason, but can be null.
     198             :   nsresult
     199             :   SpawnWorkerIfNeeded(WakeUpReason aWhy,
     200             :                       nsIRunnable* aLoadFailedRunnable,
     201             :                       bool* aNewWorkerCreated = nullptr,
     202             :                       nsILoadGroup* aLoadGroup = nullptr);
     203             : 
     204             :   ~ServiceWorkerPrivate();
     205             : 
     206             :   already_AddRefed<KeepAliveToken>
     207             :   CreateEventKeepAliveToken();
     208             : 
     209             :   // The info object owns us. It is possible to outlive it for a brief period
     210             :   // of time if there are pending waitUntil promises, in which case it
     211             :   // will be null and |SpawnWorkerIfNeeded| will always fail.
     212             :   ServiceWorkerInfo* MOZ_NON_OWNING_REF mInfo;
     213             : 
     214             :   // The WorkerPrivate object can only be closed by this class or by the
     215             :   // RuntimeService class if gecko is shutting down. Closing the worker
     216             :   // multiple times is OK, since the second attempt will be a no-op.
     217             :   RefPtr<WorkerPrivate> mWorkerPrivate;
     218             : 
     219             :   nsCOMPtr<nsITimer> mIdleWorkerTimer;
     220             : 
     221             :   // We keep a token for |dom.serviceWorkers.idle_timeout| seconds to give the
     222             :   // worker a grace period after each event.
     223             :   RefPtr<KeepAliveToken> mIdleKeepAliveToken;
     224             : 
     225             :   uint64_t mDebuggerCount;
     226             : 
     227             :   uint64_t mTokenCount;
     228             : 
     229             :   // Meant for keeping objects alive while handling requests from the worker
     230             :   // on the main thread. Access to this array is provided through
     231             :   // |StoreISupports| and |RemoveISupports|. Note that the array is also
     232             :   // cleared whenever the worker is terminated.
     233             :   nsTArray<nsCOMPtr<nsISupports>> mSupportsArray;
     234             : 
     235             :   // Array of function event worker runnables that are pending due to
     236             :   // the worker activating.  Main thread only.
     237             :   nsTArray<RefPtr<WorkerRunnable>> mPendingFunctionalEvents;
     238             : };
     239             : 
     240             : } // namespace workers
     241             : } // namespace dom
     242             : } // namespace mozilla
     243             : 
     244             : #endif // mozilla_dom_workers_serviceworkerprivate_h

Generated by: LCOV version 1.13