LCOV - code coverage report
Current view: top level - toolkit/components/places - Shutdown.h (source / functions) Hit Total Coverage
Test: output.info Lines: 2 7 28.6 %
Date: 2017-07-14 16:53:18 Functions: 1 8 12.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #ifndef mozilla_places_Shutdown_h_
       6             : #define mozilla_places_Shutdown_h_
       7             : 
       8             : #include "nsIAsyncShutdown.h"
       9             : #include "Database.h"
      10             : #include "nsProxyRelease.h"
      11             : 
      12             : namespace mozilla {
      13             : namespace places {
      14             : 
      15             : class Database;
      16             : 
      17             : /**
      18             :  * This is most of the code responsible for Places shutdown.
      19             :  *
      20             :  * PHASE 1 (Legacy clients shutdown)
      21             :  * The shutdown procedure begins when the Database singleton receives
      22             :  * profile-change-teardown (note that tests will instead notify nsNavHistory,
      23             :  * that forwards the notification to the Database instance).
      24             :  * Database::Observe first of all checks if initialization was completed
      25             :  * properly, to avoid race conditions, then it notifies "places-shutdown" to
      26             :  * legacy clients. Legacy clients are supposed to start and complete any
      27             :  * shutdown critical work in the same tick, since we won't wait for them.
      28             : 
      29             :  * PHASE 2 (Modern clients shutdown)
      30             :  * Modern clients should instead register as a blocker by passing a promise to
      31             :  * nsPIPlacesDatabase::shutdownClient (for example see sanitize.js), so they
      32             :  * block Places shutdown until the promise is resolved.
      33             :  * When profile-change-teardown is observed by async shutdown, it calls
      34             :  * ClientsShutdownBlocker::BlockShutdown. This class is registered as a teardown
      35             :  * phase blocker in Database::Init (see Database::mClientsShutdown).
      36             :  * ClientsShutdownBlocker::BlockShudown waits for all the clients registered
      37             :  * through nsPIPlacesDatabase::shutdownClient. When all the clients are done,
      38             :  * its `Done` method is invoked, and it stops blocking the shutdown phase, so
      39             :  * that it can continue.
      40             :  *
      41             :  * PHASE 3 (Connection shutdown)
      42             :  * ConnectionBlocker is registered as a profile-before-change blocker in
      43             :  * Database::Init (see Database::mConnectionShutdown).
      44             :  * When profile-before-change is observer by async shutdown, it calls
      45             :  * ConnectionShutdownBlocker::BlockShutdown.
      46             :  * This is the last chance for any Places internal work, like privacy cleanups,
      47             :  * before the connection is closed. This a places-will-close-connection
      48             :  * notification is sent to legacy clients that must complete any operation in
      49             :  * the same tick, since we won't wait for them.
      50             :  * Then the control is passed to Database::Shutdown, that executes some sanity
      51             :  * checks, clears cached statements and proceeds with asyncClose.
      52             :  * Once the connection is definitely closed, Database will call back
      53             :  * ConnectionBlocker::Complete. At this point a final
      54             :  * places-connection-closed notification is sent, for testing purposes.
      55             :  */
      56             : 
      57             : /**
      58             :  * A base AsyncShutdown blocker in charge of shutting down Places.
      59             :  */
      60             : class PlacesShutdownBlocker : public nsIAsyncShutdownBlocker
      61             : {
      62             : public:
      63             :   NS_DECL_THREADSAFE_ISUPPORTS
      64             :   NS_DECL_NSIASYNCSHUTDOWNBLOCKER
      65             : 
      66             :   explicit PlacesShutdownBlocker(const nsString& aName);
      67             : 
      68             :   /**
      69             :    * `true` if we have not started shutdown, i.e.  if
      70             :    * `BlockShutdown()` hasn't been called yet, false otherwise.
      71             :    */
      72          19 :   static bool IsStarted() {
      73          19 :     return sIsStarted;
      74             :   }
      75             : 
      76             :   // The current state, used internally and for forensics/debugging purposes.
      77             :   // Not all the states make sense for all the derived classes.
      78             :   enum States {
      79             :     NOT_STARTED,
      80             :     // Execution of `BlockShutdown` in progress.
      81             :     RECEIVED_BLOCK_SHUTDOWN,
      82             : 
      83             :     // Values specific to ClientsShutdownBlocker
      84             :     // a. Set while we are waiting for clients to do their job and unblock us.
      85             :     CALLED_WAIT_CLIENTS,
      86             :     // b. Set when all the clients are done.
      87             :     RECEIVED_DONE,
      88             : 
      89             :     // Values specific to ConnectionShutdownBlocker
      90             :     // a. Set after we notified observers that Places is closing the connection.
      91             :     NOTIFIED_OBSERVERS_PLACES_WILL_CLOSE_CONNECTION,
      92             :     // b. Set after we pass control to Database::Shutdown, and wait for it to
      93             :     // close the connection and call our `Complete` method when done.
      94             :     CALLED_STORAGESHUTDOWN,
      95             :     // c. Set when Database has closed the connection and passed control to
      96             :     // us through `Complete`.
      97             :     RECEIVED_STORAGESHUTDOWN_COMPLETE,
      98             :     // d. We have notified observers that Places has closed the connection.
      99             :     NOTIFIED_OBSERVERS_PLACES_CONNECTION_CLOSED,
     100             :   };
     101           0 :   States State() {
     102           0 :     return mState;
     103             :   }
     104             : 
     105             : protected:
     106             :   // The blocker name, also used as barrier name.
     107             :   nsString mName;
     108             :   // The current state, see States.
     109             :   States mState;
     110             :   // The barrier optionally used to wait for clients.
     111             :   nsMainThreadPtrHandle<nsIAsyncShutdownBarrier> mBarrier;
     112             :   // The parent object who registered this as a blocker.
     113             :   nsMainThreadPtrHandle<nsIAsyncShutdownClient> mParentClient;
     114             : 
     115             :   // As tests may resurrect a dead `Database`, we use a counter to
     116             :   // give the instances of `PlacesShutdownBlocker` unique names.
     117             :   uint16_t mCounter;
     118             :   static uint16_t sCounter;
     119             : 
     120             :   static Atomic<bool> sIsStarted;
     121             : 
     122           0 :   virtual ~PlacesShutdownBlocker() {}
     123             : };
     124             : 
     125             : /**
     126             :  * Blocker also used to wait for clients, through an owned barrier.
     127             :  */
     128             : class ClientsShutdownBlocker final : public PlacesShutdownBlocker
     129             :                                    , public nsIAsyncShutdownCompletionCallback
     130             : {
     131             : public:
     132             :   NS_DECL_ISUPPORTS_INHERITED
     133             :   NS_DECL_NSIASYNCSHUTDOWNCOMPLETIONCALLBACK
     134             : 
     135             :   explicit ClientsShutdownBlocker();
     136             : 
     137             :   NS_IMETHOD BlockShutdown(nsIAsyncShutdownClient* aParentClient) override;
     138             : 
     139             :   already_AddRefed<nsIAsyncShutdownClient> GetClient();
     140             : 
     141             : private:
     142           0 :   ~ClientsShutdownBlocker() {}
     143             : };
     144             : 
     145             : /**
     146             :  * Blocker used to wait when closing the database connection.
     147             :  */
     148             : class ConnectionShutdownBlocker final : public PlacesShutdownBlocker
     149             :                                       , public mozIStorageCompletionCallback
     150             : {
     151             : public:
     152             :   NS_DECL_ISUPPORTS_INHERITED
     153             :   NS_DECL_MOZISTORAGECOMPLETIONCALLBACK
     154             : 
     155             :   NS_IMETHOD BlockShutdown(nsIAsyncShutdownClient* aParentClient) override;
     156             : 
     157             :   explicit ConnectionShutdownBlocker(mozilla::places::Database* aDatabase);
     158             : 
     159             : private:
     160           0 :   ~ConnectionShutdownBlocker() {}
     161             : 
     162             :   // The owning database.
     163             :   // The cycle is broken in method Complete(), once the connection
     164             :   // has been closed by mozStorage.
     165             :   RefPtr<mozilla::places::Database> mDatabase;
     166             : };
     167             : 
     168             : } // namespace places
     169             : } // namespace mozilla
     170             : 
     171             : #endif // mozilla_places_Shutdown_h_

Generated by: LCOV version 1.13