storage/test/test_async_callbacks_with_spun_event_loops.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 #include "storage_test_harness.h"
     5 #include "prthread.h"
     6 #include "nsIEventTarget.h"
     7 #include "nsIInterfaceRequestorUtils.h"
     8 #include "mozilla/Attributes.h"
    10 #include "sqlite3.h"
    12 ////////////////////////////////////////////////////////////////////////////////
    13 //// Async Helpers
    15 /**
    16  * Spins the events loop for current thread until aCondition is true.
    17  */
    18 void
    19 spin_events_loop_until_true(const bool* const aCondition)
    20 {
    21   nsCOMPtr<nsIThread> thread(::do_GetCurrentThread());
    22   nsresult rv = NS_OK;
    23   bool processed = true;
    24   while (!(*aCondition) && NS_SUCCEEDED(rv)) {
    25     rv = thread->ProcessNextEvent(true, &processed);
    26   }
    27 }
    29 ////////////////////////////////////////////////////////////////////////////////
    30 //// mozIStorageStatementCallback implementation
    32 class UnownedCallback MOZ_FINAL : public mozIStorageStatementCallback
    33 {
    34 public:
    35   NS_DECL_ISUPPORTS
    37   // Whether the object has been destroyed.
    38   static bool sAlive;
    39   // Whether the first result was received.
    40   static bool sResult;
    41   // Whether an error was received.
    42   static bool sError;
    44   UnownedCallback(mozIStorageConnection* aDBConn)
    45   : mDBConn(aDBConn)
    46   , mCompleted(false)
    47   {
    48     sAlive = true;
    49     sResult = false;
    50     sError = false;
    51   }
    53   ~UnownedCallback()
    54   {
    55     sAlive = false;
    56     blocking_async_close(mDBConn);
    57   }
    59   NS_IMETHOD HandleResult(mozIStorageResultSet* aResultSet)
    60   {
    61     sResult = true;
    62     spin_events_loop_until_true(&mCompleted);
    63     if (!sAlive) {
    64       NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
    65     }
    66     return NS_OK;
    67   }
    69   NS_IMETHOD HandleError(mozIStorageError* aError)
    70   {
    71     sError = true;
    72     spin_events_loop_until_true(&mCompleted);
    73     if (!sAlive) {
    74       NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
    75     }
    76     return NS_OK;
    77   }
    79   NS_IMETHOD HandleCompletion(uint16_t aReason)
    80   {
    81     mCompleted = true;
    82     return NS_OK;
    83   }
    85 protected:
    86   nsCOMPtr<mozIStorageConnection> mDBConn;
    87   bool mCompleted;
    88 };
    90 NS_IMPL_ISUPPORTS(UnownedCallback, mozIStorageStatementCallback)
    92 bool UnownedCallback::sAlive = false;
    93 bool UnownedCallback::sResult = false;
    94 bool UnownedCallback::sError = false;
    96 ////////////////////////////////////////////////////////////////////////////////
    97 //// Tests
    99 void
   100 test_SpinEventsLoopInHandleResult()
   101 {
   102   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
   104   // Create a test table and populate it.
   105   nsCOMPtr<mozIStorageStatement> stmt;
   106   db->CreateStatement(NS_LITERAL_CSTRING(
   107     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
   108   ), getter_AddRefs(stmt));
   109   stmt->Execute();
   110   stmt->Finalize();
   112   db->CreateStatement(NS_LITERAL_CSTRING(
   113     "INSERT INTO test (id) VALUES (?)"
   114   ), getter_AddRefs(stmt));
   115   for (int32_t i = 0; i < 30; ++i) {
   116     stmt->BindInt32ByIndex(0, i);
   117     stmt->Execute();
   118     stmt->Reset();
   119   }
   120   stmt->Finalize();
   122   db->CreateStatement(NS_LITERAL_CSTRING(
   123     "SELECT * FROM test"
   124   ), getter_AddRefs(stmt));
   125   nsCOMPtr<mozIStoragePendingStatement> ps;
   126   do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
   127                                       getter_AddRefs(ps)));
   128   stmt->Finalize();
   130   spin_events_loop_until_true(&UnownedCallback::sResult);
   131 }
   133 void
   134 test_SpinEventsLoopInHandleError()
   135 {
   136   nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
   138   // Create a test table and populate it.
   139   nsCOMPtr<mozIStorageStatement> stmt;
   140   db->CreateStatement(NS_LITERAL_CSTRING(
   141     "CREATE TABLE test (id INTEGER PRIMARY KEY)"
   142   ), getter_AddRefs(stmt));
   143   stmt->Execute();
   144   stmt->Finalize();
   146   db->CreateStatement(NS_LITERAL_CSTRING(
   147     "INSERT INTO test (id) VALUES (1)"
   148   ), getter_AddRefs(stmt));
   149   stmt->Execute();
   150   stmt->Finalize();
   152   // This will cause a constraint error.
   153   db->CreateStatement(NS_LITERAL_CSTRING(
   154     "INSERT INTO test (id) VALUES (1)"
   155   ), getter_AddRefs(stmt));
   156   nsCOMPtr<mozIStoragePendingStatement> ps;
   157   do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
   158                                       getter_AddRefs(ps)));
   159   stmt->Finalize();
   161   spin_events_loop_until_true(&UnownedCallback::sError);
   162 }
   164 void (*gTests[])(void) = {
   165   test_SpinEventsLoopInHandleResult,
   166   test_SpinEventsLoopInHandleError,
   167 };
   169 const char *file = __FILE__;
   170 #define TEST_NAME "test async callbacks with spun event loops"
   171 #define TEST_FILE file
   172 #include "storage_test_harness_tail.h"

mercurial