@@ -917,7 +917,6 @@ struct Iterator final : public BaseIterator {
917
917
nexting_(false ),
918
918
isClosing_(false ),
919
919
ended_(false ),
920
- closeWorker_(NULL ),
921
920
state_(state),
922
921
ref_(NULL ) {
923
922
}
@@ -980,7 +979,6 @@ struct Iterator final : public BaseIterator {
980
979
bool nexting_;
981
980
bool isClosing_;
982
981
bool ended_;
983
- BaseWorker* closeWorker_;
984
982
unsigned char * state_;
985
983
std::vector<Entry> cache_;
986
984
@@ -996,7 +994,7 @@ struct Iterator final : public BaseIterator {
996
994
static void env_cleanup_hook (void * arg) {
997
995
Database* database = (Database*)arg;
998
996
999
- // Do everything that db_close () does but synchronously. We're expecting that GC
997
+ // Do everything that db.close () does but synchronously. We're expecting that GC
1000
998
// did not (yet) collect the database because that would be a user mistake (not
1001
999
// closing their db) made during the lifetime of the environment. That's different
1002
1000
// from an environment being torn down (like the main process or a worker thread)
@@ -1099,6 +1097,7 @@ NAPI_METHOD(db_open) {
1099
1097
NAPI_ARGV (3 );
1100
1098
NAPI_DB_CONTEXT ();
1101
1099
NAPI_ARGV_UTF8_NEW (location, 1 );
1100
+ NAPI_PROMISE ();
1102
1101
1103
1102
napi_value options = argv[2 ];
1104
1103
const bool createIfMissing = BooleanProperty (env, options, " createIfMissing" , true );
@@ -1116,8 +1115,6 @@ NAPI_METHOD(db_open) {
1116
1115
1117
1116
database->blockCache_ = leveldb::NewLRUCache (cacheSize);
1118
1117
1119
- NAPI_PROMISE ();
1120
-
1121
1118
OpenWorker* worker = new OpenWorker (
1122
1119
env, database, deferred, location,
1123
1120
createIfMissing, errorIfExists,
@@ -1159,36 +1156,15 @@ NAPI_METHOD(db_close) {
1159
1156
NAPI_DB_CONTEXT ();
1160
1157
NAPI_PROMISE ();
1161
1158
1159
+ // AbstractLevel should not call _close() before iterators are closed
1160
+ assert (database->iterators_ .size () == 0 );
1161
+
1162
1162
CloseWorker* worker = new CloseWorker (env, database, deferred);
1163
1163
1164
1164
if (!database->HasPriorityWork ()) {
1165
1165
worker->Queue (env);
1166
- return promise;
1167
- }
1168
-
1169
- database->pendingCloseWorker_ = worker;
1170
-
1171
- std::map<uint32_t , Iterator*> iterators = database->iterators_ ;
1172
- std::map<uint32_t , Iterator*>::iterator it;
1173
-
1174
- for (it = iterators.begin (); it != iterators.end (); ++it) {
1175
- Iterator* iterator = it->second ;
1176
-
1177
- // TODO (v2): should no longer be necessary? Also not in abstract-level v1. But
1178
- // if it is, then find a cleaner solution than creating a whole bunch of throwaway promises.
1179
- if (!iterator->isClosing_ && !iterator->hasClosed_ ) {
1180
- // napi_value iteratorPromise;
1181
- // napi_deferred iteratorDeferred;
1182
- // NAPI_STATUS_THROWS(napi_create_promise(env, &iteratorDeferred, &iteratorPromise));
1183
- // CloseIteratorWorker* worker = new CloseIteratorWorker(env, iterator, iteratorPromise, iteratorDeferred);
1184
- // iterator->isClosing_ = true;
1185
- //
1186
- // if (iterator->nexting_) {
1187
- // iterator->closeWorker_ = worker;
1188
- // } else {
1189
- // worker->Queue(env);
1190
- // }
1191
- }
1166
+ } else {
1167
+ database->pendingCloseWorker_ = worker;
1192
1168
}
1193
1169
1194
1170
return promise;
@@ -1757,9 +1733,9 @@ NAPI_METHOD(iterator_seek) {
1757
1733
NAPI_ARGV (2 );
1758
1734
NAPI_ITERATOR_CONTEXT ();
1759
1735
1760
- if (iterator-> isClosing_ || iterator-> hasClosed_ ) {
1761
- NAPI_RETURN_UNDEFINED ( );
1762
- }
1736
+ // AbstractIterator should not call _seek() after _close()
1737
+ assert (!iterator-> isClosing_ );
1738
+ assert (!iterator-> hasClosed_ );
1763
1739
1764
1740
leveldb::Slice target = ToSlice (env, argv[1 ]);
1765
1741
iterator->first_ = true ;
@@ -1801,20 +1777,16 @@ NAPI_METHOD(iterator_close) {
1801
1777
NAPI_ITERATOR_CONTEXT ();
1802
1778
NAPI_PROMISE ();
1803
1779
1804
- if (!iterator-> isClosing_ && !iterator-> hasClosed_ ) {
1805
- CloseIteratorWorker* worker = new CloseIteratorWorker (env, iterator, deferred );
1806
- iterator->isClosing_ = true ;
1780
+ // AbstractIterator should not call _close() more than once
1781
+ assert (! iterator-> isClosing_ );
1782
+ assert (! iterator->hasClosed_ ) ;
1807
1783
1808
- if (iterator->nexting_ ) {
1809
- iterator->closeWorker_ = worker;
1810
- } else {
1811
- worker->Queue (env);
1812
- }
1813
- } else {
1814
- // TODO (v2): I think we can remove the isClosing_ checks
1815
- napi_value argv = CreateCodeError (env, " LEVEL_XYZ" , " Should not happen?" );
1816
- NAPI_STATUS_THROWS (napi_reject_deferred (env, deferred, argv));
1817
- }
1784
+ // AbstractIterator should not call _close() while next() is in-progress
1785
+ assert (!iterator->nexting_ );
1786
+
1787
+ CloseIteratorWorker* worker = new CloseIteratorWorker (env, iterator, deferred);
1788
+ iterator->isClosing_ = true ;
1789
+ worker->Queue (env);
1818
1790
1819
1791
return promise;
1820
1792
}
@@ -1864,15 +1836,7 @@ struct NextWorker final : public BaseWorker {
1864
1836
}
1865
1837
1866
1838
void DoFinally (napi_env env) override {
1867
- // clean up & handle the next/close state
1868
1839
iterator_->nexting_ = false ;
1869
-
1870
- // TODO (v2): check if still needed
1871
- if (iterator_->closeWorker_ != NULL ) {
1872
- iterator_->closeWorker_ ->Queue (env);
1873
- iterator_->closeWorker_ = NULL ;
1874
- }
1875
-
1876
1840
BaseWorker::DoFinally (env);
1877
1841
}
1878
1842
@@ -1894,11 +1858,11 @@ NAPI_METHOD(iterator_nextv) {
1894
1858
NAPI_STATUS_THROWS (napi_get_value_uint32 (env, argv[1 ], &size));
1895
1859
if (size == 0 ) size = 1 ;
1896
1860
1897
- if (iterator-> isClosing_ || iterator-> hasClosed_ ) {
1898
- // TODO (v2): test, or remove
1899
- napi_value argv = CreateCodeError (env, " LEVEL_ITERATOR_NOT_OPEN " , " Iterator is not open " );
1900
- NAPI_STATUS_THROWS ( napi_reject_deferred (env, deferred, argv));
1901
- } else if (iterator->ended_ ) {
1861
+ // AbstractIterator should not call _next() or _nextv() after _close()
1862
+ assert (!iterator-> isClosing_ );
1863
+ assert (!iterator-> hasClosed_ );
1864
+
1865
+ if (iterator->ended_ ) {
1902
1866
napi_value empty;
1903
1867
napi_create_array_with_length (env, 0 , &empty);
1904
1868
napi_resolve_deferred (env, deferred, empty);
0 commit comments