Bumping manifests a=b2g-bump
[gecko.git] / storage / test / test_async_callbacks_with_spun_event_loops.cpp
blob063997ae54776fccd189b9609c1acb30a8457216
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.
18 void
19 spin_events_loop_until_true(const bool* const aCondition)
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);
29 ////////////////////////////////////////////////////////////////////////////////
30 //// mozIStorageStatementCallback implementation
32 class UnownedCallback MOZ_FINAL : public mozIStorageStatementCallback
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 explicit UnownedCallback(mozIStorageConnection* aDBConn)
45 : mDBConn(aDBConn)
46 , mCompleted(false)
48 sAlive = true;
49 sResult = false;
50 sError = false;
53 private:
54 ~UnownedCallback()
56 sAlive = false;
57 blocking_async_close(mDBConn);
60 public:
61 NS_IMETHOD HandleResult(mozIStorageResultSet* aResultSet)
63 sResult = true;
64 spin_events_loop_until_true(&mCompleted);
65 if (!sAlive) {
66 NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
68 return NS_OK;
71 NS_IMETHOD HandleError(mozIStorageError* aError)
73 sError = true;
74 spin_events_loop_until_true(&mCompleted);
75 if (!sAlive) {
76 NS_RUNTIMEABORT("The statement callback was destroyed prematurely.");
78 return NS_OK;
81 NS_IMETHOD HandleCompletion(uint16_t aReason)
83 mCompleted = true;
84 return NS_OK;
87 protected:
88 nsCOMPtr<mozIStorageConnection> mDBConn;
89 bool mCompleted;
92 NS_IMPL_ISUPPORTS(UnownedCallback, mozIStorageStatementCallback)
94 bool UnownedCallback::sAlive = false;
95 bool UnownedCallback::sResult = false;
96 bool UnownedCallback::sError = false;
98 ////////////////////////////////////////////////////////////////////////////////
99 //// Tests
101 void
102 test_SpinEventsLoopInHandleResult()
104 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
106 // Create a test table and populate it.
107 nsCOMPtr<mozIStorageStatement> stmt;
108 db->CreateStatement(NS_LITERAL_CSTRING(
109 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
110 ), getter_AddRefs(stmt));
111 stmt->Execute();
112 stmt->Finalize();
114 db->CreateStatement(NS_LITERAL_CSTRING(
115 "INSERT INTO test (id) VALUES (?)"
116 ), getter_AddRefs(stmt));
117 for (int32_t i = 0; i < 30; ++i) {
118 stmt->BindInt32ByIndex(0, i);
119 stmt->Execute();
120 stmt->Reset();
122 stmt->Finalize();
124 db->CreateStatement(NS_LITERAL_CSTRING(
125 "SELECT * FROM test"
126 ), getter_AddRefs(stmt));
127 nsCOMPtr<mozIStoragePendingStatement> ps;
128 do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
129 getter_AddRefs(ps)));
130 stmt->Finalize();
132 spin_events_loop_until_true(&UnownedCallback::sResult);
135 void
136 test_SpinEventsLoopInHandleError()
138 nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
140 // Create a test table and populate it.
141 nsCOMPtr<mozIStorageStatement> stmt;
142 db->CreateStatement(NS_LITERAL_CSTRING(
143 "CREATE TABLE test (id INTEGER PRIMARY KEY)"
144 ), getter_AddRefs(stmt));
145 stmt->Execute();
146 stmt->Finalize();
148 db->CreateStatement(NS_LITERAL_CSTRING(
149 "INSERT INTO test (id) VALUES (1)"
150 ), getter_AddRefs(stmt));
151 stmt->Execute();
152 stmt->Finalize();
154 // This will cause a constraint error.
155 db->CreateStatement(NS_LITERAL_CSTRING(
156 "INSERT INTO test (id) VALUES (1)"
157 ), getter_AddRefs(stmt));
158 nsCOMPtr<mozIStoragePendingStatement> ps;
159 do_check_success(stmt->ExecuteAsync(new UnownedCallback(db),
160 getter_AddRefs(ps)));
161 stmt->Finalize();
163 spin_events_loop_until_true(&UnownedCallback::sError);
166 void (*gTests[])(void) = {
167 test_SpinEventsLoopInHandleResult,
168 test_SpinEventsLoopInHandleError,
171 const char *file = __FILE__;
172 #define TEST_NAME "test async callbacks with spun event loops"
173 #define TEST_FILE file
174 #include "storage_test_harness_tail.h"