tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mozStorageAsyncStatementExecution.h (7784B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
      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 mozStorageAsyncStatementExecution_h
      8 #define mozStorageAsyncStatementExecution_h
      9 
     10 #include "nscore.h"
     11 #include "nsTArray.h"
     12 #include "mozilla/Mutex.h"
     13 #include "mozilla/TimeStamp.h"
     14 #include "nsThreadUtils.h"
     15 
     16 #include "SQLiteMutex.h"
     17 #include "mozIStoragePendingStatement.h"
     18 #include "mozIStorageStatementCallback.h"
     19 #include "mozStorageHelper.h"
     20 
     21 struct sqlite3_stmt;
     22 
     23 namespace mozilla {
     24 namespace storage {
     25 
     26 class Connection;
     27 class ResultSet;
     28 class StatementData;
     29 }  // namespace storage
     30 }  // namespace mozilla
     31 
     32 namespace mozilla::storage {
     33 class AsyncExecuteStatements final : public Runnable,
     34                                     public mozIStoragePendingStatement {
     35 public:
     36  NS_DECL_ISUPPORTS_INHERITED
     37  NS_DECL_NSIRUNNABLE
     38  NS_DECL_MOZISTORAGEPENDINGSTATEMENT
     39 
     40  /**
     41   * Describes the state of execution.
     42   */
     43  enum ExecutionState {
     44    PENDING = -1,
     45    COMPLETED = mozIStorageStatementCallback::REASON_FINISHED,
     46    CANCELED = mozIStorageStatementCallback::REASON_CANCELED,
     47    ERROR = mozIStorageStatementCallback::REASON_ERROR
     48  };
     49 
     50  typedef nsTArray<StatementData> StatementDataArray;
     51 
     52  /**
     53   * Executes a statement in the background, and passes results back to the
     54   * caller.
     55   *
     56   * @param aStatements
     57   *        The statements to execute and possibly bind in the background.
     58   *        Ownership is transfered from the caller.
     59   * @param aConnection
     60   *        The connection that created the statements to execute.
     61   * @param aNativeConnection
     62   *        The native Sqlite connection that created the statements to execute.
     63   * @param aCallback
     64   *        The callback that is notified of results, completion, and errors.
     65   * @param _stmt
     66   *        The handle to control the execution of the statements.
     67   */
     68  static nsresult execute(StatementDataArray&& aStatements,
     69                          Connection* aConnection, sqlite3* aNativeConnection,
     70                          mozIStorageStatementCallback* aCallback,
     71                          mozIStoragePendingStatement** _stmt);
     72 
     73  /**
     74   * Indicates when events on the calling thread should run or not.  Certain
     75   * events posted back to the calling thread should call this see if they
     76   * should run or not.
     77   *
     78   * @pre mMutex is not held
     79   *
     80   * @returns true if the event should notify still, false otherwise.
     81   */
     82  bool shouldNotify();
     83 
     84  /**
     85   * Used by notifyComplete(), notifyError() and notifyResults() to notify on
     86   * the calling thread.
     87   */
     88  nsresult notifyCompleteOnCallingThread();
     89  nsresult notifyErrorOnCallingThread(mozIStorageError* aError);
     90  nsresult notifyResultsOnCallingThread(ResultSet* aResultSet);
     91 
     92 private:
     93  AsyncExecuteStatements(StatementDataArray&& aStatements,
     94                         Connection* aConnection, sqlite3* aNativeConnection,
     95                         mozIStorageStatementCallback* aCallback);
     96  ~AsyncExecuteStatements();
     97 
     98  /**
     99   * Binds and then executes a given statement until completion, an error
    100   * occurs, or we are canceled.  If aLastStatement is true, we should set
    101   * mState accordingly.
    102   *
    103   * @pre mMutex is not held
    104   *
    105   * @param aData
    106   *        The StatementData to bind, execute, and then process.
    107   * @param aLastStatement
    108   *        Indicates if this is the last statement or not.  If it is, we have
    109   *        to set the proper state.
    110   * @returns true if we should continue to process statements, false otherwise.
    111   */
    112  bool bindExecuteAndProcessStatement(StatementData& aData,
    113                                      bool aLastStatement);
    114 
    115  /**
    116   * Executes a given statement until completion, an error occurs, or we are
    117   * canceled.  If aLastStatement is true, we should set mState accordingly.
    118   *
    119   * @pre mMutex is not held
    120   *
    121   * @param aData
    122   *        The StatementData to execute, and then process.
    123   * @param aLastStatement
    124   *        Indicates if this is the last statement or not.  If it is, we have
    125   *        to set the proper state.
    126   * @returns true if we should continue to process statements, false otherwise.
    127   */
    128  bool executeAndProcessStatement(StatementData& aData, bool aLastStatement);
    129 
    130  /**
    131   * Executes a statement to completion, properly handling any error conditions.
    132   *
    133   * @pre mMutex is not held
    134   *
    135   * @param aData
    136   *        The StatementData to execute to completion.
    137   * @returns true if results were obtained, false otherwise.
    138   */
    139  bool executeStatement(StatementData& aData);
    140 
    141  /**
    142   * Builds a result set up with a row from a given statement.  If we meet the
    143   * right criteria, go ahead and notify about this results too.
    144   *
    145   * @pre mMutex is not held
    146   *
    147   * @param aStatement
    148   *        The statement to get the row data from.
    149   */
    150  nsresult buildAndNotifyResults(sqlite3_stmt* aStatement);
    151 
    152  /**
    153   * Notifies callback about completion, and does any necessary cleanup.
    154   *
    155   * @pre mMutex is not held
    156   */
    157  nsresult notifyComplete();
    158 
    159  /**
    160   * Notifies callback about an error.
    161   *
    162   * @pre mMutex is not held
    163   * @pre mDBMutex is not held
    164   *
    165   * @param aErrorCode
    166   *        The error code defined in mozIStorageError for the error.
    167   * @param aMessage
    168   *        The error string, if any.
    169   * @param aError
    170   *        The error object to notify the caller with.
    171   */
    172  nsresult notifyError(int32_t aErrorCode, const char* aMessage);
    173  nsresult notifyError(mozIStorageError* aError);
    174 
    175  /**
    176   * Notifies the callback about a result set.
    177   *
    178   * @pre mMutex is not held
    179   */
    180  nsresult notifyResults();
    181 
    182  /**
    183   * Tests whether the current statements should be wrapped in an explicit
    184   * transaction.
    185   *
    186   * @return true if an explicit transaction is needed, false otherwise.
    187   */
    188  bool statementsNeedTransaction();
    189 
    190  StatementDataArray mStatements;
    191  RefPtr<Connection> mConnection;
    192  sqlite3* mNativeConnection;
    193  bool mHasTransaction;
    194  // Note, this may not be a threadsafe object - never addref/release off
    195  // the calling thread.  We take a reference when this is created, and
    196  // release it in the CompletionNotifier::Run() call back to this thread.
    197  nsCOMPtr<mozIStorageStatementCallback> mCallback;
    198  nsCOMPtr<nsIThread> mCallingThread;
    199  RefPtr<ResultSet> mResultSet;
    200 
    201  /**
    202   * The maximum amount of time we want to wait between results.  Defined by
    203   * MAX_MILLISECONDS_BETWEEN_RESULTS and set at construction.
    204   */
    205  const TimeDuration mMaxWait;
    206 
    207  /**
    208   * The start time since our last set of results.
    209   */
    210  TimeStamp mIntervalStart;
    211 
    212  /**
    213   * Indicates our state of execution.
    214   */
    215  ExecutionState mState;
    216 
    217  /**
    218   * Indicates if we should try to cancel at a cancelation point.
    219   */
    220  bool mCancelRequested;
    221 
    222  /**
    223   * This is the mutex that protects our state from changing between threads.
    224   * This includes the following variables:
    225   *   - mCancelRequested is only set on the calling thread while the lock is
    226   *     held.  It is always read from within the lock on the background thread,
    227   *     but not on the calling thread (see shouldNotify for why).
    228   */
    229  Mutex& mMutex;
    230 
    231  /**
    232   * The wrapped SQLite recursive connection mutex.  We use it whenever we call
    233   * sqlite3_step and care about having reliable error messages.  By taking it
    234   * prior to the call and holding it until the point where we no longer care
    235   * about the error message, the user gets reliable error messages.
    236   */
    237  SQLiteMutex& mDBMutex;
    238 };
    239 
    240 }  // namespace mozilla::storage
    241 
    242 #endif  // mozStorageAsyncStatementExecution_h