@@ -86,28 +86,37 @@ static void env_cleanup_hook(void* arg) {
86
86
* - `TransactionRollbackDo`
87
87
*/
88
88
static void IteratorCloseDo (napi_env env, Iterator* iterator, napi_value cb) {
89
+ LOG_DEBUG (" IteratorCloseDo:Calling IteratorCloseDo\n " );
89
90
CloseIteratorWorker* worker = new CloseIteratorWorker (env, iterator, cb);
90
91
iterator->isClosing_ = true ;
91
92
// The only pending work for iterator is the `NextWorker`
92
93
if (!iterator->nexting_ ) {
94
+ LOG_DEBUG (" IteratorCloseDo:Queued CloseIteratorWorker\n " );
93
95
worker->Queue (env);
96
+ LOG_DEBUG (" IteratorCloseDo:Called IteratorCloseDo\n " );
94
97
return ;
95
98
}
99
+ LOG_DEBUG (" IteratorCloseDo:Delayed CloseIteratorWorker\n " );
96
100
iterator->closeWorker_ = worker;
101
+ LOG_DEBUG (" IteratorCloseDo:Called IteratorCloseDo\n " );
97
102
}
98
103
99
104
/* *
100
105
* Used by `transactionRollback` and `dbClose`
101
106
*/
102
107
static void TransactionRollbackDo (napi_env env, Transaction* transaction,
103
108
napi_value cb) {
109
+ LOG_DEBUG (" TransactionRollbackDo:Calling TransactionRollBackDo\n " );
104
110
TransactionRollbackWorker* worker =
105
111
new TransactionRollbackWorker (env, transaction, cb);
106
112
transaction->isRollbacking_ = true ;
107
113
if (!transaction->HasPendingWork ()) {
114
+ LOG_DEBUG (" TransactionRollbackDo:Queued TransactionRollbackWorker\n " );
108
115
worker->Queue (env);
116
+ LOG_DEBUG (" TransactionRollbackDo:Called TransactionRollBackDo\n " );
109
117
return ;
110
118
}
119
+ LOG_DEBUG (" TransactionRollbackDo:Delayed TransactionRollbackWorker\n " );
111
120
transaction->closeWorker_ = worker;
112
121
napi_value noop;
113
122
napi_create_function (env, NULL , 0 , noop_callback, NULL , &noop);
@@ -119,17 +128,22 @@ static void TransactionRollbackDo(napi_env env, Transaction* transaction,
119
128
if (iterator->isClosing_ || iterator->hasClosed_ ) {
120
129
continue ;
121
130
}
131
+ LOG_DEBUG (" TransactionRollbackDo:Closing Iterator %d\n " , iterator->id_ );
122
132
IteratorCloseDo (env, iterator, noop);
123
133
}
134
+ LOG_DEBUG (" TransactionRollbackDo:Called TransactionRollBackDo\n " );
124
135
}
125
136
126
137
/* *
127
138
* Used by `snapshotRelease` and `dbClose`
128
139
*/
129
140
static void SnapshotReleaseDo (napi_env env, Snapshot* snapshot, napi_value cb) {
141
+ LOG_DEBUG (" SnapshotReleaseDo:Calling SnapshotReleaseDo\n " );
130
142
SnapshotReleaseWorker* worker = new SnapshotReleaseWorker (env, snapshot, cb);
131
143
snapshot->isReleasing_ = true ;
132
144
worker->Queue (env);
145
+ LOG_DEBUG (" SnapshotReleaseDo:Queued SnapshotReleaseWorker\n " );
146
+ LOG_DEBUG (" SnapshotReleaseDo:Called SnapshotReleaseDo\n " );
133
147
}
134
148
135
149
/* *
@@ -138,15 +152,17 @@ static void SnapshotReleaseDo(napi_env env, Snapshot* snapshot, napi_value cb) {
138
152
* with no references and no concurrent workers
139
153
*/
140
154
static void GCDatabase (napi_env env, void * data, void * hint) {
141
- LOG_DEBUG (" Garbage Collecting Database\n " );
155
+ LOG_DEBUG (" GCDatabase: Garbage Collecting Database\n " );
142
156
if (data != nullptr ) {
143
157
auto database = static_cast <Database*>(data);
144
158
napi_remove_env_cleanup_hook (env, env_cleanup_hook, database);
145
- database->Close ();
146
- database->Detach (env);
159
+ if (!database->isClosing_ && !database->hasClosed_ ) {
160
+ database->Close ();
161
+ database->Detach (env);
162
+ }
147
163
delete database;
148
164
}
149
- LOG_DEBUG (" Garbage Collected Database\n " );
165
+ LOG_DEBUG (" GCDatabase: Garbage Collected Database\n " );
150
166
}
151
167
152
168
/* *
@@ -155,12 +171,12 @@ static void GCDatabase(napi_env env, void* data, void* hint) {
155
171
* with no references and no concurrent workers
156
172
*/
157
173
static void GCBatch (napi_env env, void * data, void * hint) {
158
- LOG_DEBUG (" Garbage Collecting Batch\n " );
174
+ LOG_DEBUG (" GCBatch: Garbage Collecting Batch\n " );
159
175
if (data) {
160
176
auto batch = static_cast <Batch*>(data);
161
177
delete batch;
162
178
}
163
- LOG_DEBUG (" Garbage Collected Batch\n " );
179
+ LOG_DEBUG (" GCBatch: Garbage Collected Batch\n " );
164
180
}
165
181
166
182
/* *
@@ -169,14 +185,16 @@ static void GCBatch(napi_env env, void* data, void* hint) {
169
185
* with no references and no concurrent workers
170
186
*/
171
187
static void GCIterator (napi_env env, void * data, void * hint) {
172
- LOG_DEBUG (" Garbage Collecting Iterator\n " );
188
+ LOG_DEBUG (" GCIterator: Garbage collecting Iterator\n " );
173
189
if (data != nullptr ) {
174
190
auto iterator = static_cast <Iterator*>(data);
175
- iterator->Close ();
176
- iterator->Detach (env);
191
+ if (!iterator->isClosing_ && !iterator->hasClosed_ ) {
192
+ iterator->Close ();
193
+ iterator->Detach (env);
194
+ }
177
195
delete iterator;
178
196
}
179
- LOG_DEBUG (" Garbage Collected Iterator\n " );
197
+ LOG_DEBUG (" GCIterator: Garbage Collected Iterator\n " );
180
198
}
181
199
182
200
/* *
@@ -185,16 +203,17 @@ static void GCIterator(napi_env env, void* data, void* hint) {
185
203
* with no references and no concurrent workers
186
204
*/
187
205
static void GCTransaction (napi_env env, void * data, void * hint) {
188
- LOG_DEBUG (" Garbage Collecting Transaction\n " );
206
+ LOG_DEBUG (" GCTransaction: Garbage Collecting Transaction\n " );
189
207
if (data != nullptr ) {
190
208
auto transaction = static_cast <Transaction*>(data);
191
- if (!transaction->hasCommitted_ ) {
209
+ if (!transaction->isCommitting_ && !transaction->hasCommitted_ &&
210
+ !transaction->isRollbacking_ && !transaction->hasRollbacked_ ) {
192
211
transaction->Rollback ();
212
+ transaction->Detach (env);
193
213
}
194
- transaction->Detach (env);
195
214
delete transaction;
196
215
}
197
- LOG_DEBUG (" Garbage Collected Transaction\n " );
216
+ LOG_DEBUG (" GCTransaction: Garbage Collected Transaction\n " );
198
217
}
199
218
200
219
/* *
@@ -203,14 +222,16 @@ static void GCTransaction(napi_env env, void* data, void* hint) {
203
222
* with no references and no concurrent workers
204
223
*/
205
224
static void GCSnapshot (napi_env env, void * data, void * hint) {
206
- LOG_DEBUG (" Garbage Collecting Snapshot\n " );
225
+ LOG_DEBUG (" GCSnapshot: Garbage Collecting Snapshot\n " );
207
226
if (data != nullptr ) {
208
227
auto snapshot = static_cast <Snapshot*>(data);
209
- snapshot->Release ();
210
- snapshot->Detach (env);
228
+ if (!snapshot->isReleasing_ && !snapshot->hasReleased_ ) {
229
+ snapshot->Release ();
230
+ snapshot->Detach (env);
231
+ }
211
232
delete snapshot;
212
233
}
213
- LOG_DEBUG (" Garbage Collected Snapshot\n " );
234
+ LOG_DEBUG (" GCSnapshot: Garbage Collected Snapshot\n " );
214
235
}
215
236
216
237
/* *
@@ -219,12 +240,12 @@ static void GCSnapshot(napi_env env, void* data, void* hint) {
219
240
* with no references and no concurrent workers
220
241
*/
221
242
static void GCTransactionSnapshot (napi_env env, void * data, void * hint) {
222
- LOG_DEBUG (" Garbage Collecting TransactionSnapshot\n " );
243
+ LOG_DEBUG (" GCTransactionSnapshot: Garbage Collecting TransactionSnapshot\n " );
223
244
if (data) {
224
245
auto snapshot = static_cast <TransactionSnapshot*>(data);
225
246
delete snapshot;
226
247
}
227
- LOG_DEBUG (" Garbage Collected TransactionSnapshot\n " );
248
+ LOG_DEBUG (" GCTransactionSnapshot: Garbage Collected TransactionSnapshot\n " );
228
249
}
229
250
230
251
/* *
@@ -314,14 +335,19 @@ NAPI_METHOD(dbOpen) {
314
335
* This is asynchronous
315
336
*/
316
337
NAPI_METHOD (dbClose) {
338
+ LOG_DEBUG (" dbClose:Calling dbClose\n " );
317
339
NAPI_ARGV (2 );
318
340
NAPI_DB_CONTEXT ();
319
341
napi_value callback = argv[1 ];
320
342
CloseWorker* worker = new CloseWorker (env, database, callback);
343
+ database->isClosing_ = true ;
321
344
if (!database->HasPendingWork ()) {
345
+ LOG_DEBUG (" dbClose:Queued CloseWorker\n " );
322
346
worker->Queue (env);
347
+ LOG_DEBUG (" dbClose:Called dbClose\n " );
323
348
NAPI_RETURN_UNDEFINED ();
324
349
}
350
+ LOG_DEBUG (" dbClose:Delayed CloseWorker\n " );
325
351
database->closeWorker_ = worker;
326
352
napi_value noop;
327
353
napi_create_function (env, NULL , 0 , noop_callback, NULL , &noop);
@@ -333,6 +359,7 @@ NAPI_METHOD(dbClose) {
333
359
if (iterator->isClosing_ || iterator->hasClosed_ ) {
334
360
continue ;
335
361
}
362
+ LOG_DEBUG (" dbClose:Closing Iterator %d\n " , iterator->id_ );
336
363
IteratorCloseDo (env, iterator, noop);
337
364
}
338
365
std::map<uint32_t , Transaction*> transactions = database->transactions_ ;
@@ -344,6 +371,7 @@ NAPI_METHOD(dbClose) {
344
371
transaction->isRollbacking_ || transaction->hasRollbacked_ ) {
345
372
continue ;
346
373
}
374
+ LOG_DEBUG (" dbClose:Rollbacking Transaction %d\n " , transaction->id_ );
347
375
TransactionRollbackDo (env, transaction, noop);
348
376
}
349
377
std::map<uint32_t , Snapshot*> snapshots = database->snapshots_ ;
@@ -354,8 +382,11 @@ NAPI_METHOD(dbClose) {
354
382
if (snapshot->isReleasing_ || snapshot->hasReleased_ ) {
355
383
continue ;
356
384
}
385
+ LOG_DEBUG (" dbClose:Releasing Snapshot %d\n " , snapshot->id_ );
357
386
SnapshotReleaseDo (env, snapshot, noop);
358
387
}
388
+
389
+ LOG_DEBUG (" dbClose:Called dbClose\n " );
359
390
NAPI_RETURN_UNDEFINED ();
360
391
}
361
392
0 commit comments