diff --git a/C/Cpp_include/c4Base.hh b/C/Cpp_include/c4Base.hh index 05161acf1..ae304ca5d 100644 --- a/C/Cpp_include/c4Base.hh +++ b/C/Cpp_include/c4Base.hh @@ -37,6 +37,8 @@ struct C4Base { using alloc_slice = fleece::alloc_slice; template using Retained = fleece::Retained; + template + using Ref = fleece::Ref; }; // Forward references to internal LiteCore classes named in the public headers diff --git a/C/Cpp_include/c4Certificate.hh b/C/Cpp_include/c4Certificate.hh index 15d40da91..d703877f7 100644 --- a/C/Cpp_include/c4Certificate.hh +++ b/C/Cpp_include/c4Certificate.hh @@ -32,7 +32,7 @@ struct C4Cert final , public fleece::InstanceCountedIn , C4Base { #ifdef COUCHBASE_ENTERPRISE - static Retained fromData(slice certData); + static Ref fromData(slice certData); alloc_slice getData(bool pemEncoded); @@ -67,10 +67,10 @@ struct C4Cert final // Certificate signing requests: - static Retained createRequest(const std::vector& nameComponents, - C4CertUsage certUsages, C4KeyPair* subjectKey); + static Ref createRequest(const std::vector& nameComponents, C4CertUsage certUsages, + C4KeyPair* subjectKey); - static Retained requestFromData(slice certRequestData); + static Ref requestFromData(slice certRequestData); bool isSigned(); @@ -78,8 +78,8 @@ struct C4Cert final void sendSigningRequest(const C4Address& address, slice optionsDictFleece, const SigningCallback& callback); - Retained signRequest(const C4CertIssuerParameters& params, C4KeyPair* issuerPrivateKey, - C4Cert* C4NULLABLE issuerCert); + Ref signRequest(const C4CertIssuerParameters& params, C4KeyPair* issuerPrivateKey, + C4Cert* C4NULLABLE issuerCert); // Persistence: @@ -101,8 +101,8 @@ struct C4Cert final litecore::crypto::CertSigningRequest* assertUnsignedCert(); #endif // COUCHBASE_ENTERPRISE - litecore::crypto::Cert* C4NULLABLE asSignedCert(); - Retained _impl; + litecore::crypto::Cert* C4NULLABLE asSignedCert(); + Ref _impl; }; #ifdef COUCHBASE_ENTERPRISE @@ -112,11 +112,11 @@ struct C4Cert final struct C4KeyPair final : public fleece::RefCounted , C4Base { - static Retained generate(C4KeyPairAlgorithm algorithm, unsigned sizeInBits, bool persistent); + static Ref generate(C4KeyPairAlgorithm algorithm, unsigned sizeInBits, bool persistent); - static Retained fromPublicKeyData(slice publicKeyData); + static Ref fromPublicKeyData(slice publicKeyData); - static Retained fromPrivateKeyData(slice privateKeyData, slice passwordOrNull); + static Ref fromPrivateKeyData(slice privateKeyData, slice passwordOrNull); bool hasPrivateKey(); @@ -136,8 +136,8 @@ struct C4KeyPair final // Externally-Implemented Key-Pairs: - static Retained fromExternal(C4KeyPairAlgorithm algorithm, size_t keySizeInBits, void* externalKey, - const C4ExternalKeyCallbacks& callbacks); + static Ref fromExternal(C4KeyPairAlgorithm algorithm, size_t keySizeInBits, void* externalKey, + const C4ExternalKeyCallbacks& callbacks); // Internal: litecore::crypto::PrivateKey* C4NULLABLE getPrivateKey(); @@ -147,10 +147,10 @@ struct C4KeyPair final explicit C4KeyPair(litecore::crypto::Key*); ~C4KeyPair() override; - Retained getPublicKey(); + Ref getPublicKey(); litecore::crypto::PersistentPrivateKey* getPersistentPrivateKey(); - Retained _impl; + Ref _impl; }; #endif // COUCHBASE_ENTERPRISE diff --git a/C/Cpp_include/c4Collection.hh b/C/Cpp_include/c4Collection.hh index f333940cc..2fe811034 100644 --- a/C/Cpp_include/c4Collection.hh +++ b/C/Cpp_include/c4Collection.hh @@ -92,7 +92,7 @@ struct C4Collection // Queries & Indexes: /// Same as the C4Database method, but the query will refer to this collection by default. - Retained newQuery(C4QueryLanguage language, slice queryExpr, int* outErrorPos) const; + Ref newQuery(C4QueryLanguage language, slice queryExpr, int* outErrorPos) const; /// Returns true if it created or replaced the index, false if it already exists. virtual bool createIndex(slice name, slice indexSpec, C4QueryLanguage indexLanguage, C4IndexType indexType, diff --git a/C/Cpp_include/c4Database.hh b/C/Cpp_include/c4Database.hh index 562b860f9..fe263ecb5 100644 --- a/C/Cpp_include/c4Database.hh +++ b/C/Cpp_include/c4Database.hh @@ -61,13 +61,13 @@ struct C4Database [[nodiscard]] static bool deleteNamed(slice name, slice inDirectory); [[nodiscard]] static bool deleteAtPath(slice path); - static Retained openNamed(slice name, const Config&); + static Ref openNamed(slice name, const Config&); - static Retained openAtPath(slice path, C4DatabaseFlags, const C4EncryptionKey* C4NULLABLE = nullptr); + static Ref openAtPath(slice path, C4DatabaseFlags, const C4EncryptionKey* C4NULLABLE = nullptr); static void shutdownLiteCore(); - Retained openAgain() const; + Ref openAgain() const; virtual void close() = 0; virtual void closeAndDeleteFile() = 0; @@ -216,22 +216,21 @@ struct C4Database // Queries & Indexes: - Retained newQuery(C4QueryLanguage language, slice queryExpression, - int* C4NULLABLE outErrorPos = nullptr) const; + Ref newQuery(C4QueryLanguage language, slice queryExpression, int* C4NULLABLE outErrorPos = nullptr) const; // Replicator: - Retained newReplicator(C4Address serverAddress, slice remoteDatabaseName, - const C4ReplicatorParameters& params, slice logPrefix = {}); + Ref newReplicator(C4Address serverAddress, slice remoteDatabaseName, + const C4ReplicatorParameters& params, slice logPrefix = {}); - Retained newIncomingReplicator(C4Socket* openSocket, const C4ReplicatorParameters& params, - slice logPrefix = {}); - Retained newIncomingReplicator(litecore::websocket::WebSocket* openSocket, - const C4ReplicatorParameters& params, slice logPrefix = {}); + Ref newIncomingReplicator(C4Socket* openSocket, const C4ReplicatorParameters& params, + slice logPrefix = {}); + Ref newIncomingReplicator(litecore::websocket::WebSocket* openSocket, + const C4ReplicatorParameters& params, slice logPrefix = {}); #ifdef COUCHBASE_ENTERPRISE - Retained newLocalReplicator(C4Database* otherLocalDB, const C4ReplicatorParameters& params, - slice logPrefix = {}); + Ref newLocalReplicator(C4Database* otherLocalDB, const C4ReplicatorParameters& params, + slice logPrefix = {}); #endif alloc_slice getCookies(const C4Address&); diff --git a/C/Cpp_include/c4Document.hh b/C/Cpp_include/c4Document.hh index 0983045cc..4adc2db65 100644 --- a/C/Cpp_include/c4Document.hh +++ b/C/Cpp_include/c4Document.hh @@ -41,7 +41,7 @@ struct C4Document // NOTE: Instances are created with database->getDocument or database->putDocument. /// Creates a new instance identical to this one, except its `extraInfo` is unset. - virtual Retained copy() const = 0; + virtual Ref copy() const = 0; // Accessors: diff --git a/C/Cpp_include/c4Index.hh b/C/Cpp_include/c4Index.hh index f59e8c0de..0c3ab3ee3 100644 --- a/C/Cpp_include/c4Index.hh +++ b/C/Cpp_include/c4Index.hh @@ -58,8 +58,8 @@ struct C4Index C4Index(C4Collection* coll, std::string name) : _collection(coll), _name(std::move(name)) {} - Retained _collection; - std::string _name; + Ref _collection; + std::string _name; }; #ifdef COUCHBASE_ENTERPRISE @@ -102,14 +102,14 @@ struct C4IndexUpdater final private: friend struct C4IndexImpl; - C4IndexUpdater(Retained, C4Collection*); + C4IndexUpdater(Ref, C4Collection*); ~C4IndexUpdater(); // Invariants: _update != nullptr || (finish() has been called) - bool hasFinished() const { return !_update; } + bool hasFinished() const { return !_update.isValid(); } - Retained _update; - Retained _collection; + Ref _update; + Ref _collection; }; #endif diff --git a/C/Cpp_include/c4Listener.hh b/C/Cpp_include/c4Listener.hh index b7f5c4887..4266b45a1 100644 --- a/C/Cpp_include/c4Listener.hh +++ b/C/Cpp_include/c4Listener.hh @@ -89,7 +89,7 @@ struct C4Listener final C4Listener(const C4Listener&) = delete; // internal use only - C4Listener(C4ListenerConfig const& config, Retained impl); + C4Listener(C4ListenerConfig const& config, Ref impl); private: C4Listener(C4Listener&&) noexcept; diff --git a/C/Cpp_include/c4Query.hh b/C/Cpp_include/c4Query.hh index 2c2439664..236e8e1b1 100644 --- a/C/Cpp_include/c4Query.hh +++ b/C/Cpp_include/c4Query.hh @@ -37,13 +37,12 @@ struct C4Query final , C4Base { public: /// Creates a new query on a database. - static Retained newQuery(C4Database*, C4QueryLanguage, slice queryExpression, int* C4NULLABLE outErrorPos); + static Ref newQuery(C4Database*, C4QueryLanguage, slice queryExpression, int* C4NULLABLE outErrorPos); /// Creates a new query on the collection's database. /// If the query does not refer to a collection by name (e.g. "FROM airlines"), /// it will use the given collection instead of the default one. - static Retained newQuery(C4Collection*, C4QueryLanguage, slice queryExpression, - int* C4NULLABLE outErrorPos); + static Ref newQuery(C4Collection*, C4QueryLanguage, slice queryExpression, int* C4NULLABLE outErrorPos); unsigned columnCount() const noexcept; slice columnTitle(unsigned col) const LIFETIMEBOUND; @@ -80,10 +79,10 @@ struct C4Query final friend struct C4Query; friend class litecore::C4QueryObserverImpl; explicit Enumerator(C4Query*, slice encodedParameters = fleece::nullslice); - explicit Enumerator(Retained e); + explicit Enumerator(C4Query*, Ref); - Retained _enum; - Retained _query; + Ref _enum; + Ref _query; }; /// Runs the query, returning an enumerator. Use it like this: @@ -100,7 +99,7 @@ struct C4Query final using ObserverCallback = std::function; - Retained observe(ObserverCallback); + Ref observe(ObserverCallback); protected: friend class litecore::C4QueryObserverImpl; @@ -115,32 +114,30 @@ struct C4Query final struct KeyCmp { using is_transparent = void; - bool operator()(const Retained& r1, - const Retained& r2) const { + bool operator()(const Ref& r1, + const Ref& r2) const { return r1.get() < r2.get(); } - bool operator()(const Retained& r1, - const litecore::C4QueryObserverImpl* p2) const { + bool operator()(const Ref& r1, const litecore::C4QueryObserverImpl* p2) const { return r1.get() < p2; } - bool operator()(const litecore::C4QueryObserverImpl* p1, - const Retained& r2) const { + bool operator()(const litecore::C4QueryObserverImpl* p1, const Ref& r2) const { return p1 < r2.get(); } }; - using ObserverSet = std::set, KeyCmp>; + using ObserverSet = std::set, KeyCmp>; - Retained _createEnumerator(slice params); + Ref _createEnumerator(slice params); Retained wrapEnumerator(litecore::QueryEnumerator* C4NULLABLE); void liveQuerierUpdated(litecore::QueryEnumerator* C4NULLABLE, C4Error err); void liveQuerierStopped(); void notifyObservers(const ObserverSet& observers, litecore::QueryEnumerator* C4NULLABLE, C4Error err); - Retained _database; - Retained _query; + Ref _database; + Ref _query; alloc_slice _parameters; Retained _bgQuerier; std::unique_ptr _bgQuerierDelegate; @@ -158,7 +155,7 @@ struct C4QueryObserver , C4Base { public: /// Creates a new query on a database. - static Retained newQueryObserver(C4Query* query, C4Query::ObserverCallback cb, void* ctx); + static Ref newQueryObserver(C4Query* query, C4Query::ObserverCallback cb, void* ctx); virtual ~C4QueryObserver() = default; @@ -177,8 +174,8 @@ struct C4QueryObserver protected: explicit C4QueryObserver(C4Query* query) : _query(query) {} - Retained _query; - C4Error _currentError{}; + Ref _query; + C4Error _currentError{}; }; C4_ASSUME_NONNULL_END diff --git a/C/c4Certificate.cc b/C/c4Certificate.cc index 099e22f9b..444b3d00b 100644 --- a/C/c4Certificate.cc +++ b/C/c4Certificate.cc @@ -76,7 +76,7 @@ CertSigningRequest* C4Cert::assertUnsignedCert() { return (CertSigningRequest*)_impl.get(); } -Retained C4Cert::fromData(slice certData) { return new C4Cert(new Cert(certData)); } +Ref C4Cert::fromData(slice certData) { return new C4Cert(new Cert(certData)); } alloc_slice C4Cert::getData(bool pemEncoded) { return _impl->data(pemEncoded ? KeyFormat::PEM : KeyFormat::DER); } @@ -162,8 +162,8 @@ Retained C4Cert::getNextInChain() { // Certificate signing requests: -Retained C4Cert::createRequest(const std::vector& nameComponents, C4CertUsage certUsages, - C4KeyPair* subjectKey) { +Ref C4Cert::createRequest(const std::vector& nameComponents, C4CertUsage certUsages, + C4KeyPair* subjectKey) { vector name; SubjectAltNames altNames; for ( auto& component : nameComponents ) { @@ -178,7 +178,7 @@ Retained C4Cert::createRequest(const std::vector& n return new C4Cert(new CertSigningRequest(params, subjectKey->getPrivateKey())); } -Retained C4Cert::requestFromData(slice certRequestData) { +Ref C4Cert::requestFromData(slice certRequestData) { # ifdef ENABLE_CERT_REQUEST return new C4Cert(new CertSigningRequest(certRequestData)); # else @@ -205,8 +205,8 @@ void C4Cert::sendSigningRequest(const C4Address& address, slice optionsDictFleec // NOLINTEND(readability-convert-member-functions-to-static) -Retained C4Cert::signRequest(const C4CertIssuerParameters& c4Params, C4KeyPair* issuerPrivateKey, - C4Cert* C4NULLABLE issuerC4Cert) { +Ref C4Cert::signRequest(const C4CertIssuerParameters& c4Params, C4KeyPair* issuerPrivateKey, + C4Cert* C4NULLABLE issuerC4Cert) { auto csr = assertUnsignedCert(); auto privateKey = issuerPrivateKey->getPrivateKey(); AssertParam(privateKey != nullptr, "No private key"); @@ -275,7 +275,7 @@ C4KeyPair::C4KeyPair(Key* key) : _impl(key) { Assert(key); } C4KeyPair::~C4KeyPair() = default; -Retained C4KeyPair::getPublicKey() { +Ref C4KeyPair::getPublicKey() { if ( PrivateKey* priv = getPrivateKey(); priv ) return priv->publicKey(); else return (PublicKey*)_impl.get(); @@ -288,7 +288,7 @@ PersistentPrivateKey* C4KeyPair::getPersistentPrivateKey() { return nullptr; } -Retained C4KeyPair::generate(C4KeyPairAlgorithm algorithm, unsigned sizeInBits, bool persistent) { +Ref C4KeyPair::generate(C4KeyPairAlgorithm algorithm, unsigned sizeInBits, bool persistent) { AssertParam(algorithm == kC4RSA, "Invalid algorithm"); Retained privateKey; if ( persistent ) { @@ -303,11 +303,9 @@ Retained C4KeyPair::generate(C4KeyPairAlgorithm algorithm, unsigned s return new C4KeyPair(privateKey); } -Retained C4KeyPair::fromPublicKeyData(slice publicKeyData) { - return new C4KeyPair(new PublicKey(publicKeyData)); -} +Ref C4KeyPair::fromPublicKeyData(slice publicKeyData) { return new C4KeyPair(new PublicKey(publicKeyData)); } -Retained C4KeyPair::fromPrivateKeyData(slice privateKeyData, slice passwordOrNull) { +Ref C4KeyPair::fromPrivateKeyData(slice privateKeyData, slice passwordOrNull) { return new C4KeyPair(new PrivateKey(privateKeyData, passwordOrNull)); } @@ -380,8 +378,8 @@ namespace litecore { } fleece::alloc_slice publicKeyRawData() override { - alloc_slice data(publicKeyDERData()); - Retained publicKey = new PublicKey(data); + alloc_slice data(publicKeyDERData()); + Ref publicKey = new PublicKey(data); return publicKey->data(KeyFormat::Raw); } @@ -410,8 +408,8 @@ namespace litecore { } // namespace litecore -Retained C4KeyPair::fromExternal(C4KeyPairAlgorithm algorithm, size_t keySizeInBits, void* externalKey, - const C4ExternalKeyCallbacks& callbacks) { +Ref C4KeyPair::fromExternal(C4KeyPairAlgorithm algorithm, size_t keySizeInBits, void* externalKey, + const C4ExternalKeyCallbacks& callbacks) { AssertParam(algorithm == kC4RSA, "Invalid algorithm"); return new C4KeyPair(new ExternalKeyPair(keySizeInBits, externalKey, callbacks)); } diff --git a/C/c4Collection.cc b/C/c4Collection.cc index d5d03c935..847194d38 100644 --- a/C/c4Collection.cc +++ b/C/c4Collection.cc @@ -45,7 +45,7 @@ C4Document* C4Collection::documentContainingValue(FLValue value) noexcept { return doc; } -Retained C4Collection::newQuery(C4QueryLanguage language, slice expr, int* errPos) const { +Ref C4Collection::newQuery(C4QueryLanguage language, slice expr, int* errPos) const { if ( _usuallyFalse(!_database) ) failClosed(); return C4Query::newQuery(const_cast(this), language, expr, errPos); } diff --git a/C/c4Database.cc b/C/c4Database.cc index 976eba4a9..075902038 100644 --- a/C/c4Database.cc +++ b/C/c4Database.cc @@ -129,7 +129,7 @@ constexpr const char* kInvalidDbNameMsgTemplate = "and starts with a letter or digit, followed by letters, digits, dashes, " "or underscores."; -/*static*/ Retained C4Database::openNamed(slice name, const Config& config) { +/*static*/ Ref C4Database::openNamed(slice name, const Config& config) { if ( !(config.flags & kC4DB_ReadOnly) && !isValidDbName(name) ) { Warn(kInvalidDbNameMsgTemplate, name.asString().c_str()); } @@ -140,7 +140,7 @@ constexpr const char* kInvalidDbNameMsgTemplate = return DatabaseImpl::open(path, oldConfig); } -/*static*/ Retained C4Database::openAtPath(slice path, C4DatabaseFlags flags, const C4EncryptionKey* key) { +/*static*/ Ref C4Database::openAtPath(slice path, C4DatabaseFlags flags, const C4EncryptionKey* key) { C4DatabaseConfig config = {flags}; if ( key ) config.encryptionKey = *key; return DatabaseImpl::open(FilePath(path, ""), config); @@ -168,7 +168,7 @@ constexpr const char* kInvalidDbNameMsgTemplate = /*static*/ void C4Database::shutdownLiteCore() { SQLiteDataFile::shutdown(); } -Retained C4Database::openAgain() const { +Ref C4Database::openAgain() const { auto config = _config; config.flags |= kC4DB_NoHousekeeping; return openNamed(getName(), config); @@ -195,7 +195,7 @@ C4Database::C4Database(std::string name, std::string dir, const C4DatabaseConfig #pragma mark - QUERIES: -Retained C4Database::newQuery(C4QueryLanguage language, slice expr, int* errPos) const { +Ref C4Database::newQuery(C4QueryLanguage language, slice expr, int* errPos) const { return C4Query::newQuery(getDefaultCollectionSafe(), language, expr, errPos); } diff --git a/C/c4Document.cc b/C/c4Document.cc index 56c82fd85..831a8b1c3 100644 --- a/C/c4Document.cc +++ b/C/c4Document.cc @@ -195,8 +195,8 @@ Retained C4Document::update(slice revBody, C4RevisionFlags revFlags) // First the fast path: try to save directly via putNewRevision. Do this on a copy, not on // myself, because putNewRevision changes the instance, and if it fails I don't want to keep // those changes. - Retained savedDoc = this->copy(); - C4Error myErr; + Ref savedDoc = this->copy(); + C4Error myErr; if ( savedDoc->checkNewRev(parentRev, revFlags, false, &myErr) && savedDoc->putNewRevision(rq, &myErr) ) { // Fast path succeeded! return savedDoc; diff --git a/C/c4Index.cc b/C/c4Index.cc index cdfb7a639..bba4bc23a 100644 --- a/C/c4Index.cc +++ b/C/c4Index.cc @@ -106,7 +106,7 @@ struct C4IndexImpl final : public C4Index { Retained beginUpdate(size_t limit) { if ( !_lazy ) _lazy = new LazyIndex(asInternal(_collection)->keyStore(), _name); Retained update = _lazy->beginUpdate(limit); - if ( update ) return new C4IndexUpdater(std::move(update), _collection); + if ( update ) return new C4IndexUpdater(std::move(update).asRef(), _collection); else return nullptr; } @@ -143,7 +143,7 @@ bool C4Index::isTrained() const { return _collection->isIndexTrained(_name); } Retained C4Index::beginUpdate(size_t limit) { return asInternal(this)->beginUpdate(limit); } -C4IndexUpdater::C4IndexUpdater(Retained u, C4Collection* c) +C4IndexUpdater::C4IndexUpdater(Ref u, C4Collection* c) : _update(std::move(u)), _collection(c) {} C4IndexUpdater::~C4IndexUpdater() = default; @@ -189,8 +189,8 @@ bool C4IndexUpdater::finish() { C4Database::Transaction txn(db); bool done = _update->finish(asInternal(db)->transaction()); txn.commit(); - _update = nullptr; - _collection = nullptr; + std::move(_update).destroy(); + std::move(_collection).destroy(); return done; } diff --git a/C/c4Query.cc b/C/c4Query.cc index 2fb752794..984e3bc21 100644 --- a/C/c4Query.cc +++ b/C/c4Query.cc @@ -35,9 +35,9 @@ C4Query::C4Query(C4Collection* coll, C4QueryLanguage language, slice queryExpres C4Query::~C4Query() = default; -Retained C4Query::newQuery(C4Collection* coll, C4QueryLanguage language, slice expr, int* outErrorPos) { +Ref C4Query::newQuery(C4Collection* coll, C4QueryLanguage language, slice expr, int* outErrorPos) { try { - return retained(new C4Query(coll, language, expr)); + return new C4Query(coll, language, expr); } catch ( Query::parseError& x ) { if ( outErrorPos ) { *outErrorPos = x.errorPosition; } throw; @@ -47,7 +47,7 @@ Retained C4Query::newQuery(C4Collection* coll, C4QueryLanguage language } } -Retained C4Query::newQuery(C4Database* db, C4QueryLanguage language, slice expr, int* outErrorPos) { +Ref C4Query::newQuery(C4Database* db, C4QueryLanguage language, slice expr, int* outErrorPos) { return newQuery(db->getDefaultCollection(), language, expr, outErrorPos); } @@ -80,7 +80,7 @@ void C4Query::setParameters(slice parameters) { #pragma mark - ENUMERATOR: -Retained C4Query::_createEnumerator(slice encodedParameters) { +Ref C4Query::_createEnumerator(slice encodedParameters) { Query::Options options(encodedParameters ? encodedParameters : parameters()); return _query->createEnumerator(&options); } @@ -99,7 +99,8 @@ C4QueryEnumerator* C4Query::createEnumerator(slice encodedParameters) { C4Query::Enumerator::Enumerator(C4Query* query, slice encodedParameters) : _enum(query->_createEnumerator(encodedParameters)), _query(query->_query) {} -C4Query::Enumerator::Enumerator(Retained e) : _enum(std::move(e)) {} +C4Query::Enumerator::Enumerator(C4Query* query, Ref e) + : _enum(std::move(e)), _query(query->_query) {} C4Query::Enumerator::Enumerator(Enumerator&& c4e) noexcept : _enum(std::move(c4e._enum)), _query(std::move(c4e._query)) {} @@ -107,8 +108,8 @@ C4Query::Enumerator::Enumerator(Enumerator&& c4e) noexcept C4Query::Enumerator::~Enumerator() = default; void C4Query::Enumerator::close() noexcept { - _enum = nullptr; - _query = nullptr; + std::move(_enum).destroy(); + std::move(_query).destroy(); } int64_t C4Query::Enumerator::rowCount() const { return _enum->getRowCount(); } @@ -118,7 +119,6 @@ bool C4Query::Enumerator::next() { return _enum->next(); } void C4Query::Enumerator::seek(int64_t rowIndex) { _enum->seek(rowIndex); } bool C4Query::Enumerator::restart() { - Assert(_query); auto newEnum = _enum->refresh(_query); if ( !newEnum ) return false; _enum = newEnum; @@ -171,7 +171,7 @@ class C4Query::LiveQuerierDelegate : public LiveQuerier::Delegate { Retained _query; }; -Retained C4Query::observe(std::function callback) { +Ref C4Query::observe(std::function callback) { return C4QueryObserverImpl::newQueryObserver(this, callback); } diff --git a/C/c4QueryImpl.hh b/C/c4QueryImpl.hh index 80f2f9145..1e8189037 100644 --- a/C/c4QueryImpl.hh +++ b/C/c4QueryImpl.hh @@ -44,7 +44,7 @@ namespace litecore { // NOLINTEND(cppcoreguidelines-pro-type-member-init) QueryEnumerator* enumerator() const { - if ( !_enum ) error::_throw(error::InvalidParameter, "Query enumerator has been closed"); + if ( !_enum.isValid() ) error::_throw(error::InvalidParameter, "Query enumerator has been closed"); return _enum; } @@ -87,15 +87,15 @@ namespace litecore { return nullptr; } - void close() noexcept { _enum = nullptr; } + void close() noexcept { std::move(_enum).destroy(); } bool usesEnumerator(QueryEnumerator* e) const { return e == _enum; } private: - Retained _database; - Retained _query; - Retained _enum; - bool _hasFullText; + Ref _database; + Ref _query; + Ref _enum; + bool _hasFullText; }; inline C4QueryEnumeratorImpl* asInternal(C4QueryEnumerator* e) { return (C4QueryEnumeratorImpl*)e; } @@ -103,7 +103,7 @@ namespace litecore { // Internal implementation of C4QueryObserver class C4QueryObserverImpl : public C4QueryObserver { public: - static Retained newQueryObserver(C4Query* query, C4Query::ObserverCallback callback) { + static Ref newQueryObserver(C4Query* query, C4Query::ObserverCallback callback) { return new C4QueryObserverImpl(query, callback); } @@ -131,9 +131,9 @@ namespace litecore { C4Query::Enumerator getEnumerator(bool forget) override { if ( _currentError.code ) _currentError.raise(); - Retained e = _currentEnumerator->enumerator(); + Ref e = _currentEnumerator->enumerator(); if ( forget ) _currentEnumerator = nullptr; - return C4Query::Enumerator(std::move(e)); + return C4Query::Enumerator(_query, std::move(e)); } private: diff --git a/Crypto/Certificate.cc b/Crypto/Certificate.cc index 41f454626..827901947 100644 --- a/Crypto/Certificate.cc +++ b/Crypto/Certificate.cc @@ -508,14 +508,14 @@ namespace litecore::crypto { mbedtls_pk_context* CertSigningRequest::keyContext() { return &_csr->pk; } - Retained CertSigningRequest::sign(const Cert::IssuerParameters& issuerParams, PrivateKey* issuerKeyPair, - Cert* issuerCert) { + Ref CertSigningRequest::sign(const Cert::IssuerParameters& issuerParams, PrivateKey* issuerKeyPair, + Cert* issuerCert) { Cert::SubjectParameters subjectParams(subjectName()); subjectParams.keyUsage = keyUsage(); subjectParams.nsCertType = nsCertType(); subjectParams.subjectAltNames = subjectAltNames(); - auto cert = retained(new Cert( - Cert::create(subjectParams, subjectPublicKey().get(), issuerParams, issuerKeyPair, issuerCert))); + auto cert = make_retained( + Cert::create(subjectParams, subjectPublicKey().get(), issuerParams, issuerKeyPair, issuerCert)); if ( issuerCert ) { auto issuerCopy = retained(new Cert(issuerCert->dataOfChain())); cert->append(issuerCopy); diff --git a/Crypto/Certificate.hh b/Crypto/Certificate.hh index c65dfa016..a0f9e13cf 100644 --- a/Crypto/Certificate.hh +++ b/Crypto/Certificate.hh @@ -159,7 +159,7 @@ namespace litecore::crypto { virtual SubjectAltNames subjectAltNames() = 0; /** The subject's public key. */ - fleece::Retained subjectPublicKey() { return new PublicKey(this); } + fleece::Ref subjectPublicKey() { return new PublicKey(this); } protected: virtual fleece::slice derData() = 0; @@ -268,8 +268,8 @@ namespace litecore::crypto { struct Identity : public fleece::RefCounted { Identity(Cert* NONNULL, PrivateKey* NONNULL); - fleece::Retained const cert; - fleece::Retained const privateKey; + fleece::Ref const cert; + fleece::Ref const privateKey; }; /** A request for an X.509 certificate, containing the subject's name and public key, @@ -293,8 +293,8 @@ namespace litecore::crypto { SubjectAltNames subjectAltNames() override; /** Signs the request, returning the completed Cert. */ - fleece::Retained sign(const Cert::IssuerParameters&, PrivateKey* issuerKeyPair NONNULL, - Cert* issuerCert = nullptr); + fleece::Ref sign(const Cert::IssuerParameters&, PrivateKey* issuerKeyPair NONNULL, + Cert* issuerCert = nullptr); protected: CertSigningRequest(); diff --git a/Crypto/PublicKey+Apple.mm b/Crypto/PublicKey+Apple.mm index 063479cba..881ee9f38 100644 --- a/Crypto/PublicKey+Apple.mm +++ b/Crypto/PublicKey+Apple.mm @@ -367,7 +367,7 @@ virtual int _sign(int/*mbedtls_md_type_t*/ mbedDigestAlgorithm, // Public function to generate a new key-pair - Retained PersistentPrivateKey::generateRSA(unsigned keySizeInBits) { + Ref PersistentPrivateKey::generateRSA(unsigned keySizeInBits) { @autoreleasepool { LogTo(TLSLogDomain, "Generating %u-bit RSA key-pair in Keychain", keySizeInBits); char timestr[100] = "LiteCore "; @@ -384,7 +384,7 @@ virtual int _sign(int/*mbedtls_md_type_t*/ mbedDigestAlgorithm, privateKey = SecKeyCreateRandomKey((CFDictionaryRef)params, &error); if (!privateKey) { warnCFError(error, "SecKeyCreateRandomKey"); - return nullptr; + error::_throw(error::CryptoError, "Generating RSA key failed"); } publicKey = SecKeyCopyPublicKey(privateKey); @@ -581,7 +581,7 @@ virtual int _sign(int/*mbedtls_md_type_t*/ mbedDigestAlgorithm, NSData* certData = attrs[(id)kSecValueData]; Assert(certData); - Retained cert = new Cert(slice(certData)); + Ref cert = new Cert(slice(certData)); // Create and evaluate trust to get certificate chain: SecCertificateRef certRef = (__bridge SecCertificateRef)attrs[(id)kSecValueRef]; @@ -782,7 +782,7 @@ virtual int _sign(int/*mbedtls_md_type_t*/ mbedDigestAlgorithm, root->append(cert); } CFRelease(certs); - return root; + return root.asRef(); } } diff --git a/Crypto/PublicKey+Windows.cc b/Crypto/PublicKey+Windows.cc index d6cf7dd49..3fdd75224 100644 --- a/Crypto/PublicKey+Windows.cc +++ b/Crypto/PublicKey+Windows.cc @@ -300,7 +300,7 @@ namespace litecore::crypto { atomic _keyPair; }; - Retained PersistentPrivateKey::generateRSA(unsigned keySizeInBits) { + Ref PersistentPrivateKey::generateRSA(unsigned keySizeInBits) { LogTo(TLSLogDomain, "Generating %u-bit RSA key-pair in Keychain", keySizeInBits); char timestr[100] = "LiteCore "; wchar_t wtimestr[100]; @@ -436,7 +436,7 @@ namespace litecore::crypto { const auto* const winCert = getWinCert(persistentID); if ( !winCert ) { return nullptr; } - Retained cert = new Cert(slice(winCert->pbCertEncoded, winCert->cbCertEncoded)); + Ref cert = new Cert(slice(winCert->pbCertEncoded, winCert->cbCertEncoded)); const auto* const winChain = getCertChain(winCert); DEFER { diff --git a/Crypto/PublicKey.cc b/Crypto/PublicKey.cc index 3cd5a6f5b..46446b71f 100644 --- a/Crypto/PublicKey.cc +++ b/Crypto/PublicKey.cc @@ -89,9 +89,9 @@ namespace litecore::crypto { }); } - Retained PrivateKey::generateTemporaryRSA(unsigned keySizeInBits) { - Retained key = new PrivateKey(); - auto ctx = key->context(); + Ref PrivateKey::generateTemporaryRSA(unsigned keySizeInBits) { + Ref key = new PrivateKey(); + auto ctx = key->context(); TRY(mbedtls_pk_setup(ctx, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))); LogTo(TLSLogDomain, "Generating %u-bit RSA key-pair...", keySizeInBits); TRY(mbedtls_rsa_gen_key(mbedtls_pk_rsa(*ctx), mbedtls_ctr_drbg_random, RandomNumberContext(), keySizeInBits, diff --git a/Crypto/PublicKey.hh b/Crypto/PublicKey.hh index ce271d51d..aedecb771 100644 --- a/Crypto/PublicKey.hh +++ b/Crypto/PublicKey.hh @@ -91,7 +91,7 @@ namespace litecore::crypto { /** Creates an in-memory key-pair for temporary use. Mostly useful only for testing, since the private key is exposed and difficult to save securely. */ - static fleece::Retained generateTemporaryRSA(unsigned keySizeInBits); + static fleece::Ref generateTemporaryRSA(unsigned keySizeInBits); bool isPrivate() override { return true; } @@ -107,7 +107,7 @@ namespace litecore::crypto { virtual bool isPrivateKeyDataAvailable() { return true; } /** The public key. */ - fleece::Retained publicKey() { return new PublicKey(publicKeyData(KeyFormat::Raw)); } + fleece::Ref publicKey() { return new PublicKey(publicKeyData(KeyFormat::Raw)); } protected: PrivateKey() = default; @@ -159,7 +159,7 @@ namespace litecore::crypto { public: /** Generates a new RSA key-pair. The key-pair is stored persistently (e.g. in the iOS / macOS Keychain) associated with the given label. */ - static fleece::Retained generateRSA(unsigned keySizeInBits); + static fleece::Ref generateRSA(unsigned keySizeInBits); /** Loads an existing stored key-pair that matches the given public key. */ static fleece::Retained withPublicKey(PublicKey* NONNULL); diff --git a/LiteCore/Database/CollectionImpl.hh b/LiteCore/Database/CollectionImpl.hh index 9fed6a93d..fc700f4c8 100644 --- a/LiteCore/Database/CollectionImpl.hh +++ b/LiteCore/Database/CollectionImpl.hh @@ -132,7 +132,7 @@ namespace litecore { options.sortOption = kUnsorted; RecordEnumerator e(keyStore(), options); while ( e.next() ) { - Retained doc = _documentFactory->newDocumentInstance(e.record()); + Ref doc = _documentFactory->newDocumentInstance(e.record()); doc->selectCurrentRevision(); do { if ( doc->loadRevisionBody() ) { @@ -151,13 +151,13 @@ namespace litecore { return _documentFactory.get(); } - virtual Retained newDocumentInstance(const litecore::Record& record) { + Ref newDocumentInstance(const litecore::Record& record) { return documentFactory()->newDocumentInstance(record); } Retained getDocument(slice docID, bool mustExist, C4DocContentLevel content) const override { - auto doc = documentFactory()->newDocumentInstance(docID, ContentOption(content)); - if ( mustExist && !doc->exists() ) doc = nullptr; + Ref doc = documentFactory()->newDocumentInstance(docID, ContentOption(content)); + if ( mustExist && !doc->exists() ) return nullptr; return doc; } @@ -302,12 +302,12 @@ namespace litecore { DebugAssert(rq.save, "putNewDoc optimization works only if rq.save is true"); Record record(rq.docID); if ( !rq.docID.buf ) record.setKey(C4Document::createDocID()); - Retained doc = documentFactory()->newDocumentInstance(record); - int commonAncestorIndex; + Ref doc = documentFactory()->newDocumentInstance(record); + int commonAncestorIndex; if ( rq.existingRevision ) commonAncestorIndex = doc->putExistingRevision(rq, nullptr); else commonAncestorIndex = doc->putNewRevision(rq, nullptr) ? 0 : -1; - if ( commonAncestorIndex < 0 ) doc = nullptr; + if ( commonAncestorIndex < 0 ) return {nullptr, commonAncestorIndex}; return {doc, commonAncestorIndex}; } diff --git a/LiteCore/Database/DatabaseImpl.cc b/LiteCore/Database/DatabaseImpl.cc index b87297b4f..5686c8fe1 100644 --- a/LiteCore/Database/DatabaseImpl.cc +++ b/LiteCore/Database/DatabaseImpl.cc @@ -53,8 +53,8 @@ namespace litecore { #pragma mark - OPENING / CLOSING: - Retained DatabaseImpl::open(const FilePath& path, C4DatabaseConfig config) { - Retained db = new DatabaseImpl(path, config); + Ref DatabaseImpl::open(const FilePath& path, C4DatabaseConfig config) { + Ref db = new DatabaseImpl(path, config); db->open(path); return db; } diff --git a/LiteCore/Database/DatabaseImpl.hh b/LiteCore/Database/DatabaseImpl.hh index bebc4c21d..45dd4e3f8 100644 --- a/LiteCore/Database/DatabaseImpl.hh +++ b/LiteCore/Database/DatabaseImpl.hh @@ -53,7 +53,7 @@ namespace litecore { : public C4Database , public DataFile::Delegate { public: - static Retained open(const FilePath& path, C4DatabaseConfig config); + static Ref open(const FilePath& path, C4DatabaseConfig config); FilePath filePath() const { return _dataFile->filePath().dir(); } @@ -177,7 +177,7 @@ namespace litecore { C4DocumentVersioning checkDocumentVersioning(); - using CollectionsMap = std::unordered_map>; + using CollectionsMap = std::unordered_map>; unique_ptr _dataFile; // Underlying DataFile mutable std::recursive_mutex _collectionsMutex; diff --git a/LiteCore/Database/DocumentFactory.hh b/LiteCore/Database/DocumentFactory.hh index a1066ef75..b344287ad 100644 --- a/LiteCore/Database/DocumentFactory.hh +++ b/LiteCore/Database/DocumentFactory.hh @@ -34,8 +34,8 @@ namespace litecore { [[nodiscard]] virtual bool isFirstGenRevID(slice revID) const { return false; } - virtual Retained newDocumentInstance(slice docID, ContentOption) = 0; - virtual Retained newDocumentInstance(const Record&) = 0; + virtual Ref newDocumentInstance(slice docID, ContentOption) = 0; + virtual Ref newDocumentInstance(const Record&) = 0; virtual std::vector findAncestors(const std::vector& docIDs, const std::vector& revIDs, unsigned maxAncestors, diff --git a/LiteCore/Database/LiveQuerier.hh b/LiteCore/Database/LiveQuerier.hh index 45c1165d6..0c9c31144 100644 --- a/LiteCore/Database/LiveQuerier.hh +++ b/LiteCore/Database/LiveQuerier.hh @@ -72,7 +72,7 @@ namespace litecore { void _dbChanged(clock::time_point); void _currentResult(CurrentResultCallback callback); - Retained _database; // The database + Ref _database; // The database BackgroundDB* _backgroundDB; // Shadow DB on background thread Delegate* _delegate; // Whom ya gonna call? alloc_slice _expression; // The query text diff --git a/LiteCore/Database/TreeDocument.cc b/LiteCore/Database/TreeDocument.cc index c29282c59..66c2463af 100644 --- a/LiteCore/Database/TreeDocument.cc +++ b/LiteCore/Database/TreeDocument.cc @@ -50,7 +50,7 @@ namespace litecore { if ( other._selectedRev ) _selectedRev = _revTree[other._selectedRev->revID]; } - Retained copy() const override { return new TreeDocument(*this); } + Ref copy() const override { return new TreeDocument(*this); } void init() { _revTree.owner = this; @@ -650,11 +650,11 @@ namespace litecore { #pragma mark - FACTORY: - Retained TreeDocumentFactory::newDocumentInstance(slice docID, ContentOption c) { + Ref TreeDocumentFactory::newDocumentInstance(slice docID, ContentOption c) { return new TreeDocument(collection(), docID, c); } - Retained TreeDocumentFactory::newDocumentInstance(const Record& rec) { + Ref TreeDocumentFactory::newDocumentInstance(const Record& rec) { return new TreeDocument(collection(), rec); } diff --git a/LiteCore/Database/TreeDocument.hh b/LiteCore/Database/TreeDocument.hh index 26b1c91ca..352da2e75 100644 --- a/LiteCore/Database/TreeDocument.hh +++ b/LiteCore/Database/TreeDocument.hh @@ -23,9 +23,9 @@ namespace litecore { public: explicit TreeDocumentFactory(C4Collection* coll) : DocumentFactory(coll) {} - Retained newDocumentInstance(slice docID, ContentOption) override; - Retained newDocumentInstance(const Record&) override; - [[nodiscard]] bool isFirstGenRevID(slice revID) const override; + Ref newDocumentInstance(slice docID, ContentOption) override; + Ref newDocumentInstance(const Record&) override; + [[nodiscard]] bool isFirstGenRevID(slice revID) const override; std::vector findAncestors(const std::vector& docIDs, const std::vector& revIDs, unsigned maxAncestors, bool mustHaveBodies, diff --git a/LiteCore/Database/Upgrader.cc b/LiteCore/Database/Upgrader.cc index 9e52bedd0..7549f51d9 100644 --- a/LiteCore/Database/Upgrader.cc +++ b/LiteCore/Database/Upgrader.cc @@ -42,7 +42,7 @@ namespace litecore { Upgrader(const FilePath& oldPath, const FilePath& newPath, C4DatabaseConfig config) : Upgrader(oldPath, DatabaseImpl::open(newPath, asTreeVersioning(config))) {} - Upgrader(const FilePath& oldPath, Retained newDB) + Upgrader(const FilePath& oldPath, Ref newDB) : _oldPath(oldPath) , _oldDB(oldPath["db.sqlite3"].path(), SQLite::OPEN_READWRITE) // * , _newDB(std::move(newDB)) @@ -163,7 +163,7 @@ namespace litecore { // Convert the JSON body to Fleece: alloc_slice body; { - Retained doc = convertBody(getColumnAsSlice(*_currentRev, 4)); + Ref doc = convertBody(getColumnAsSlice(*_currentRev, 4)); if ( hasAttachments ) copyAttachments(doc); body = doc->allocedData(); } @@ -191,7 +191,7 @@ namespace litecore { } // Converts a JSON document body to Fleece. - Retained convertBody(slice json) { + Ref convertBody(slice json) { Encoder& enc = _newDB->sharedEncoder(); JSONConverter converter(enc); if ( !converter.encodeJSON(json) ) error::_throw(error::CorruptRevisionData, "invalid JSON data"); @@ -259,7 +259,7 @@ namespace litecore { FilePath _oldPath; SQLite::Database _oldDB; - Retained _newDB; + Ref _newDB; FilePath _attachments; unique_ptr _currentRev, _parentRevs; }; diff --git a/LiteCore/Database/VectorDocument.cc b/LiteCore/Database/VectorDocument.cc index 19d975cd6..ab6898f39 100644 --- a/LiteCore/Database/VectorDocument.cc +++ b/LiteCore/Database/VectorDocument.cc @@ -52,7 +52,7 @@ namespace litecore { VectorDocument(const VectorDocument& other) : C4Document(other), _doc(other._doc), _remoteID(other._remoteID) {} - Retained copy() const override { return new VectorDocument(*this); } + Ref copy() const override { return new VectorDocument(*this); } ~VectorDocument() override { _doc.owner = nullptr; } @@ -699,11 +699,11 @@ namespace litecore { #pragma mark - FACTORY: - Retained VectorDocumentFactory::newDocumentInstance(slice docID, ContentOption c) { + Ref VectorDocumentFactory::newDocumentInstance(slice docID, ContentOption c) { return new VectorDocument(collection(), docID, c); } - Retained VectorDocumentFactory::newDocumentInstance(const Record& record) { + Ref VectorDocumentFactory::newDocumentInstance(const Record& record) { return new VectorDocument(collection(), record); } diff --git a/LiteCore/Database/VectorDocument.hh b/LiteCore/Database/VectorDocument.hh index a7c3c8773..ad1c3305b 100644 --- a/LiteCore/Database/VectorDocument.hh +++ b/LiteCore/Database/VectorDocument.hh @@ -22,8 +22,8 @@ namespace litecore { public: explicit VectorDocumentFactory(C4Collection* db) : DocumentFactory(db) {} - Retained newDocumentInstance(slice docID, ContentOption) override; - Retained newDocumentInstance(const Record&) override; + Ref newDocumentInstance(slice docID, ContentOption) override; + Ref newDocumentInstance(const Record&) override; std::vector findAncestors(const std::vector& docIDs, const std::vector& revIDs, unsigned maxAncestors, bool mustHaveBodies, diff --git a/LiteCore/Logging/LogObserver.cc b/LiteCore/Logging/LogObserver.cc index 0e20ec344..ac60fed5b 100644 --- a/LiteCore/Logging/LogObserver.cc +++ b/LiteCore/Logging/LogObserver.cc @@ -102,7 +102,7 @@ namespace litecore { } void LogObservers::notify(RawLogEntry const& entry, const char* format, va_list args) { - fleece::smallVector, 4> curObservers; + fleece::smallVector, 4> curObservers; { // Temporarily lock, to copy the list of observers that will be notified: unique_lock lock(_mutex); diff --git a/LiteCore/Logging/Logging_Internal.hh b/LiteCore/Logging/Logging_Internal.hh index f17340840..4e7695b56 100644 --- a/LiteCore/Logging/Logging_Internal.hh +++ b/LiteCore/Logging/Logging_Internal.hh @@ -59,7 +59,7 @@ namespace litecore { private: std::mutex mutable _mutex; // Sorted by increasing LogLevel: Debug, Verbose, Info, Warning, Error - std::vector, LogLevel>> _observers; + std::vector, LogLevel>> _observers; }; } // namespace litecore diff --git a/LiteCore/Query/LazyIndex.cc b/LiteCore/Query/LazyIndex.cc index 21d8f3a33..9f2a58a43 100644 --- a/LiteCore/Query/LazyIndex.cc +++ b/LiteCore/Query/LazyIndex.cc @@ -106,8 +106,8 @@ namespace litecore { enc["startSeq"] = int64_t(startSeq); enc["limit"] = limit; enc.endDict(); - Query::Options options(enc.finish()); - Retained e = _query->createEnumerator(&options); + Query::Options options(enc.finish()); + Ref e = _query->createEnumerator(&options); if ( e->getRowCount() > 0 ) update = new LazyIndexUpdate(this, dimension, startSeq, curSeq, indexedSequences, e, limit); } @@ -116,7 +116,7 @@ namespace litecore { // No vectors to index; mark index as up-to-date: indexedSequences.add(sequence_t{1}, curSeq + 1); updateIndexedSequences(indexedSequences); - break; + break; // and return nullptr } else if ( update->count() == 0 ) { // No vectors for the caller to compute; finish the update now: ExclusiveTransaction txn(_db); @@ -159,7 +159,7 @@ namespace litecore { # pragma mark - LAZY INDEX UPDATE: LazyIndexUpdate::LazyIndexUpdate(LazyIndex* manager, unsigned dimension, sequence_t firstSeq, sequence_t atSeq, - SequenceSet indexedSeqs, Retained e, size_t limit) + SequenceSet indexedSeqs, Ref e, size_t limit) : _manager(manager) , _firstSeq(firstSeq) , _atSeq(atSeq) @@ -260,7 +260,7 @@ namespace litecore { _items.clear(); _manager->updateIndexedSequences(newIndexedSequences); - _manager = nullptr; + std::move(_manager).destroy(); return newIndexedSequences.contains(sequence_t{1}, curSeq + 1); } diff --git a/LiteCore/Query/LazyIndex.hh b/LiteCore/Query/LazyIndex.hh index db9a93fbe..176310165 100644 --- a/LiteCore/Query/LazyIndex.hh +++ b/LiteCore/Query/LazyIndex.hh @@ -88,7 +88,7 @@ namespace litecore { private: friend class LazyIndex; LazyIndexUpdate(LazyIndex*, unsigned dimension, sequence_t firstSeq, sequence_t curSeq, SequenceSet indexedSeqs, - Retained, size_t limit); + Ref, size_t limit); using VectorPtr = std::unique_ptr; @@ -106,7 +106,7 @@ namespace litecore { ItemStatus status; ///< True if client is skipping this vector for now }; - Retained _manager; // Owning LazyIndex + Ref _manager; // Owning LazyIndex sequence_t _firstSeq; sequence_t _lastSeq; sequence_t _atSeq; // KeyStore's lastSequence at time of query diff --git a/LiteCore/Query/SQLiteQuery.cc b/LiteCore/Query/SQLiteQuery.cc index 7aaa43c04..ee786ed2c 100644 --- a/LiteCore/Query/SQLiteQuery.cc +++ b/LiteCore/Query/SQLiteQuery.cc @@ -349,7 +349,7 @@ namespace litecore { , _recording(recording) , _iter(_recording->asArray()) {} - Retained _recording; + Ref _recording; Array::iterator _iter; unsigned _1stCustomResultColumn{0}; // Column index of the 1st column declared in JSON bool _hasFullText{false}; @@ -511,7 +511,7 @@ namespace litecore { } private: - Retained _query; + Ref _query; Query::Options _options; sequence_t _lastSequence; // DB's lastSequence at the time the query ran uint64_t _purgeCount; // DB's purgeCount at the time the query ran @@ -521,7 +521,7 @@ namespace litecore { }; // The factory method that creates a SQLite Query. - Retained SQLiteDataFile::compileQuery(slice selectorExpression, QueryLanguage language, KeyStore* keyStore) { + Ref SQLiteDataFile::compileQuery(slice selectorExpression, QueryLanguage language, KeyStore* keyStore) { if ( !keyStore ) keyStore = &defaultKeyStore(); return new SQLiteQuery(*this, selectorExpression, language, asSQLiteKeyStore(keyStore)); } diff --git a/LiteCore/RevTrees/RevTreeRecord.hh b/LiteCore/RevTrees/RevTreeRecord.hh index a55360f8e..3e64c2e14 100644 --- a/LiteCore/RevTrees/RevTreeRecord.hh +++ b/LiteCore/RevTrees/RevTreeRecord.hh @@ -99,9 +99,9 @@ namespace litecore { void updateScope(); alloc_slice addScope(const alloc_slice& body); - KeyStore& _store; - Record _rec; - std::vector> _fleeceScopes; - ContentOption _contentLoaded{}; + KeyStore& _store; + Record _rec; + std::vector> _fleeceScopes; + ContentOption _contentLoaded{}; }; } // namespace litecore diff --git a/LiteCore/Storage/DataFile+Shared.hh b/LiteCore/Storage/DataFile+Shared.hh index ea016e147..8ee048889 100644 --- a/LiteCore/Storage/DataFile+Shared.hh +++ b/LiteCore/Storage/DataFile+Shared.hh @@ -33,7 +33,7 @@ namespace litecore { , public fleece::InstanceCountedIn , public Logging { public: - static Retained forPath(const FilePath& path, DataFile* dataFile) { + static fleece::Ref forPath(const FilePath& path, DataFile* dataFile) { string pathStr = path.canonicalPath(); unique_lock lock(sFileMapMutex); Retained file = sFileMap[pathStr]; @@ -47,7 +47,7 @@ namespace litecore { lock.unlock(); if ( dataFile ) file->addDataFile(dataFile); - return file; + return file.asRef(); } static size_t openCountOnPath(const FilePath& path) { @@ -124,7 +124,7 @@ namespace litecore { return i->second; } - Retained addSharedObject(const string& key, RefCounted* object) { + Ref addSharedObject(const string& key, RefCounted* object) { lock_guard lock(_mutex); auto e = _sharedObjects.emplace(key, object); return e.first->second; @@ -146,13 +146,13 @@ namespace litecore { private: - mutex _transactionMutex; // Mutex for transactions - condition_variable _transactionCond; // For waiting on the mutex - ExclusiveTransaction* _transaction{nullptr}; // Currently active Transaction object - vector _dataFiles; // Open DataFiles on this File - unordered_map> _sharedObjects; - bool _condemned{false}; // Prevents db from being opened or deleted - mutex _mutex; // Mutex for non-transaction state + mutex _transactionMutex; // Mutex for transactions + condition_variable _transactionCond; // For waiting on the mutex + ExclusiveTransaction* _transaction{nullptr}; // Currently active Transaction object + vector _dataFiles; // Open DataFiles on this File + unordered_map> _sharedObjects; + bool _condemned{false}; // Prevents db from being opened or deleted + mutex _mutex; // Mutex for non-transaction state static unordered_map sFileMap; static mutex sFileMapMutex; diff --git a/LiteCore/Storage/DataFile.cc b/LiteCore/Storage/DataFile.cc index f9c753342..a567fafcd 100644 --- a/LiteCore/Storage/DataFile.cc +++ b/LiteCore/Storage/DataFile.cc @@ -190,7 +190,7 @@ namespace litecore { Retained DataFile::sharedObject(const string& key) { return _shared->sharedObject(key); } - Retained DataFile::addSharedObject(const string& key, RefCounted* object) { + Ref DataFile::addSharedObject(const string& key, RefCounted* object) { return _shared->addSharedObject(key, object); } @@ -201,7 +201,7 @@ namespace litecore { void DataFile::deleteDataFile() { deleteDataFile(this, nullptr, _shared, factory()); } bool DataFile::Factory::deleteFile(const FilePath& path, const Options* options) { - Retained shared = Shared::forPath(path, nullptr); + Ref shared = Shared::forPath(path, nullptr); return DataFile::deleteDataFile(nullptr, options, shared, *this); } diff --git a/LiteCore/Storage/DataFile.hh b/LiteCore/Storage/DataFile.hh index 1db61a2c9..421591c2c 100644 --- a/LiteCore/Storage/DataFile.hh +++ b/LiteCore/Storage/DataFile.hh @@ -138,8 +138,8 @@ namespace litecore { //////// QUERIES: /** Creates a database query object. */ - virtual Retained compileQuery(slice expr, QueryLanguage = QueryLanguage::kJSON, - KeyStore* defaultKeyStore = nullptr) = 0; + virtual Ref compileQuery(slice expr, QueryLanguage = QueryLanguage::kJSON, + KeyStore* defaultKeyStore = nullptr) = 0; /** Private API to run a raw (e.g. SQL) query, for diagnostic purposes only */ virtual fleece::alloc_slice rawQuery(const std::string& query) = 0; @@ -196,7 +196,7 @@ namespace litecore { //////// SHARED OBJECTS: Retained sharedObject(const std::string& key); - Retained addSharedObject(const std::string& key, RefCounted*); + Ref addSharedObject(const std::string& key, RefCounted*); //////// FACTORY: diff --git a/LiteCore/Storage/KeyStore.cc b/LiteCore/Storage/KeyStore.cc index 5260944e1..268df2d08 100644 --- a/LiteCore/Storage/KeyStore.cc +++ b/LiteCore/Storage/KeyStore.cc @@ -75,7 +75,7 @@ namespace litecore { rec.setExists(); } - Retained KeyStore::compileQuery(slice expr, QueryLanguage language) { + Ref KeyStore::compileQuery(slice expr, QueryLanguage language) { return dataFile().compileQuery(expr, language, this); } diff --git a/LiteCore/Storage/KeyStore.hh b/LiteCore/Storage/KeyStore.hh index 3c170a4e5..87b4a929b 100644 --- a/LiteCore/Storage/KeyStore.hh +++ b/LiteCore/Storage/KeyStore.hh @@ -184,7 +184,7 @@ namespace litecore { //////// Queries: /** A convenience that delegates to the DataFile, passing this as the defaultKeyStore. */ - Retained compileQuery(slice expr, QueryLanguage = QueryLanguage::kJSON); + Ref compileQuery(slice expr, QueryLanguage = QueryLanguage::kJSON); //////// Indexing: diff --git a/LiteCore/Storage/SQLiteDataFile.hh b/LiteCore/Storage/SQLiteDataFile.hh index 12efcdf4d..38394b796 100644 --- a/LiteCore/Storage/SQLiteDataFile.hh +++ b/LiteCore/Storage/SQLiteDataFile.hh @@ -104,7 +104,7 @@ namespace litecore { /// Each array item is an index row; its items are its column values. void inspectIndex(slice name, int64_t& outRowCount, alloc_slice* outRows = nullptr); - Retained compileQuery(slice expression, QueryLanguage, KeyStore*) override; + Ref compileQuery(slice expression, QueryLanguage, KeyStore*) override; // Deprecated in favor of enableExtension! static void setExtensionPath(string); diff --git a/LiteCore/Support/Actor.hh b/LiteCore/Support/Actor.hh index d655bac84..ea60caf89 100644 --- a/LiteCore/Support/Actor.hh +++ b/LiteCore/Support/Actor.hh @@ -123,7 +123,7 @@ namespace litecore::actor { Use this when registering callbacks, e.g. with a Future.*/ template std::function _asynchronize(const char* methodName, std::function fn) { - Retained ret(this); + Ref ret(this); return [=](Args... arg) mutable { ret->_mailbox.enqueue(methodName, ACTOR_BIND_FN(fn, arg)); }; } diff --git a/LiteCore/Support/Base.hh b/LiteCore/Support/Base.hh index 4eaf5ba56..bd3299413 100644 --- a/LiteCore/Support/Base.hh +++ b/LiteCore/Support/Base.hh @@ -41,6 +41,7 @@ namespace litecore { using fleece::alloc_slice; using fleece::function_ref; using fleece::nullslice; + using fleece::Ref; using fleece::RefCounted; using fleece::Retained; using fleece::slice; diff --git a/LiteCore/Support/Batcher.hh b/LiteCore/Support/Batcher.hh index 710353e85..67aff701e 100644 --- a/LiteCore/Support/Batcher.hh +++ b/LiteCore/Support/Batcher.hh @@ -22,14 +22,14 @@ #include namespace litecore::actor { - using fleece::Retained; + using fleece::Ref; static constexpr int AnyGen = INT_MAX; /** A simple queue that adds objects one at a time and sends them to its target in a batch. */ template class Batcher { public: - using Items = std::unique_ptr>>; + using Items = std::unique_ptr>>; Batcher(std::function processNow, std::function processLater, Timer::duration latency = {}, size_t capacity = 0) @@ -44,7 +44,7 @@ namespace litecore::actor { std::lock_guard lock(_mutex); if ( !_items ) { - _items.reset(new std::vector>); + _items.reset(new std::vector>); _items->reserve(_capacity ? _capacity : 200); } _items->push_back(item); diff --git a/LiteCore/Support/DatabasePool.cc b/LiteCore/Support/DatabasePool.cc index 4ee7ea7d1..98cc57a3f 100644 --- a/LiteCore/Support/DatabasePool.cc +++ b/LiteCore/Support/DatabasePool.cc @@ -248,7 +248,6 @@ namespace litecore { // Called by BorrowedDatabase's destructor and its reset method. void DatabasePool::returnDatabase(Ref db) { - DebugAssert(db); unique_lock lock(_mutex); Cache& cache = (db->getConfiguration().flags & kC4DB_ReadOnly) ? _readOnly : _readWrite; diff --git a/LiteCore/Support/ThreadedMailbox.hh b/LiteCore/Support/ThreadedMailbox.hh index 0e069e518..7758945b7 100644 --- a/LiteCore/Support/ThreadedMailbox.hh +++ b/LiteCore/Support/ThreadedMailbox.hh @@ -22,6 +22,7 @@ #include namespace litecore::actor { + using fleece::Ref; using fleece::RefCounted; using fleece::Retained; diff --git a/Networking/BLIP/BLIPConnection.cc b/Networking/BLIP/BLIPConnection.cc index 321937846..021a4b457 100644 --- a/Networking/BLIP/BLIPConnection.cc +++ b/Networking/BLIP/BLIPConnection.cc @@ -53,7 +53,7 @@ namespace litecore::blip { static LogDomain BLIPMessagesLog("BLIPMessages", LogLevel::None); /** Queue of outgoing messages; each message gets to send one frame in turn. */ - class MessageQueue : public vector> { + class MessageQueue : public vector> { public: MessageQueue() = default; @@ -62,7 +62,7 @@ namespace litecore::blip { bool contains(MessageOut* msg) const { return find(begin(), end(), msg) != end(); } [[nodiscard]] MessageOut* findMessage(MessageNo msgNo, bool isResponse) const { - auto i = find_if(begin(), end(), [&](const Retained& msg) { + auto i = find_if(begin(), end(), [&](const Ref& msg) { return msg->number() == msgNo && msg->isResponse() == isResponse; }); if ( i == end() ) return nullptr; @@ -71,7 +71,7 @@ namespace litecore::blip { Retained pop() { if ( empty() ) return nullptr; - Retained msg(front()); + Ref msg(front()); erase(begin()); return msg; } @@ -91,7 +91,7 @@ namespace litecore::blip { : public actor::Actor , public websocket::Delegate { private: - using MessageMap = unordered_map>; + using MessageMap = unordered_map>; using HandlerKey = pair; using RequestHandlers = map; @@ -141,9 +141,7 @@ namespace litecore::blip { } } - void queueMessage(MessageOut* msg) { - enqueue(FUNCTION_TO_QUEUE(BLIPIO::_queueMessage), Retained(msg)); - } + void queueMessage(MessageOut* msg) { enqueue(FUNCTION_TO_QUEUE(BLIPIO::_queueMessage), Ref(msg)); } void setRequestHandler(std::string profile, bool atBeginning, Connection::RequestHandler handler) { enqueue(FUNCTION_TO_QUEUE(BLIPIO::_setRequestHandler), std::move(profile), atBeginning, std::move(handler)); @@ -247,7 +245,7 @@ namespace litecore::blip { resetWebSocket(); // thread-safe of _webSocket = nullptr; if ( _connection ) { - Retained holdOn(this); + Ref holdOn(this); if ( _closingWithError ) { status.reason = kException; status.code = _closingWithError->code; @@ -272,7 +270,7 @@ namespace litecore::blip { /** Implementation of public queueMessage() method. Adds a new message to the outgoing queue and wakes up the queue. */ // Cannot use const& because it breaks Actor::enqueue - void _queueMessage(Retained msg) { // NOLINT(performance-unnecessary-value-param) + void _queueMessage(Ref msg) { // NOLINT(performance-unnecessary-value-param) if ( !_webSocket || _closingWithError ) { logInfo("Can't send %s #%" PRIu64 "; socket is closed", kMessageTypeNames[msg->type()], msg->number()); msg->disconnected(); @@ -488,7 +486,7 @@ namespace litecore::blip { } } - wsMessage = nullptr; // free the frame + std::move(wsMessage).destroy(); // free the frame } } catch ( const std::exception& x ) { @@ -652,7 +650,7 @@ namespace litecore::blip { /** Public API to send a new request. */ void Connection::sendRequest(MessageBuilder& mb) { - Retained message = new MessageOut(this, mb, 0); + Ref message = new MessageOut(this, mb, 0); DebugAssert(message->type() == kRequestType); send(message); } diff --git a/Networking/BLIP/LoopbackProvider.hh b/Networking/BLIP/LoopbackProvider.hh index 24c2b0741..06b52a18d 100644 --- a/Networking/BLIP/LoopbackProvider.hh +++ b/Networking/BLIP/LoopbackProvider.hh @@ -95,9 +95,9 @@ namespace litecore::websocket { void received(Message* message, actor::delay_t latency = actor::delay_t::zero()) { if ( latency == actor::delay_t::zero() ) { - _driver->enqueue(FUNCTION_TO_QUEUE(Driver::_received), retained(message)); + _driver->enqueue(FUNCTION_TO_QUEUE(Driver::_received), retainedRef(message)); } else { - _driver->enqueue(FUNCTION_TO_QUEUE(Driver::_queueMessage), retained(message)); + _driver->enqueue(FUNCTION_TO_QUEUE(Driver::_queueMessage), retainedRef(message)); _driver->enqueueAfter(latency, FUNCTION_TO_QUEUE(Driver::_dequeueMessage)); } } @@ -117,8 +117,8 @@ namespace litecore::websocket { ~LoopbackMessage() override { _webSocket->ack(_size); } private: - size_t _size; - Retained _webSocket; + size_t _size; + Ref _webSocket; }; // The internal Actor that does the real work @@ -203,7 +203,7 @@ namespace litecore::websocket { if ( _peer ) { Assert(_state == State::connected); logDebug("SEND: %s", formatMsg(msg, binary).c_str()); - Retained message(new LoopbackMessage(_webSocket, msg, binary)); + Ref message(new LoopbackMessage(_webSocket, msg, binary)); _peer->received(message, _latency); } else { logInfo("SEND: Failed, socket is closed"); @@ -211,20 +211,20 @@ namespace litecore::websocket { } // Cannot use const& because it breaks Actor::enqueue - void _queueMessage(Retained message) // NOLINT(performance-unnecessary-value-param) + void _queueMessage(Ref message) // NOLINT(performance-unnecessary-value-param) { _msgWaitBuffer.push_back(message); } void _dequeueMessage() { Assert(!_msgWaitBuffer.empty()); - Retained msg = _msgWaitBuffer.front(); + Ref msg = _msgWaitBuffer.front(); _msgWaitBuffer.pop_front(); _received(msg); } // Cannot use const& because it breaks Actor::enqueue - virtual void _received(Retained message) { // NOLINT(performance-unnecessary-value-param) + virtual void _received(Ref message) { // NOLINT(performance-unnecessary-value-param) if ( !connected() ) return; logDebug("RECEIVED: %s", formatMsg(message->data, message->binary).c_str()); _webSocket->delegateWeak()->invoke(&Delegate::onWebSocketMessage, message); @@ -297,13 +297,13 @@ namespace litecore::websocket { private: friend class LoopbackWebSocket; - Retained _webSocket; - const actor::delay_t _latency{0.0}; - Retained _peer; - std::atomic _bufferedBytes{0}; - State _state{State::unconnected}; - std::deque> _msgWaitBuffer; - Headers _responseHeaders; + Retained _webSocket; + const actor::delay_t _latency{0.0}; + Retained _peer; + std::atomic _bufferedBytes{0}; + State _state{State::unconnected}; + std::deque> _msgWaitBuffer; + Headers _responseHeaders; }; }; diff --git a/Networking/BLIP/Message.cc b/Networking/BLIP/Message.cc index 8ed9cf5bd..02e839715 100644 --- a/Networking/BLIP/Message.cc +++ b/Networking/BLIP/Message.cc @@ -242,11 +242,11 @@ namespace litecore::blip { _unackedBytes += frameSize; if ( _unackedBytes >= kIncomingAckThreshold ) { // Send an ACK after enough data has been received of this message: - MessageType msgType = isResponse() ? kAckResponseType : kAckRequestType; - uint8_t buf[kMaxVarintLen64]; - alloc_slice payload(buf, PutUVarInt(buf, _rawBytesReceived)); - Retained ack = new MessageOut( - _connection, (FrameFlags)(FrameFlags(msgType) | kUrgent | kNoReply), payload, nullptr, _number); + MessageType msgType = isResponse() ? kAckResponseType : kAckRequestType; + uint8_t buf[kMaxVarintLen64]; + alloc_slice payload(buf, PutUVarInt(buf, _rawBytesReceived)); + Ref ack = new MessageOut(_connection, (FrameFlags)(FrameFlags(msgType) | kUrgent | kNoReply), + payload, nullptr, _number); _connection->send(ack); _unackedBytes = 0; } @@ -315,7 +315,7 @@ namespace litecore::blip { Assert(!_responded); _responded = true; if ( mb.type == kRequestType ) mb.type = kResponseType; - Retained message = new MessageOut(_connection, mb, _number); + Ref message = new MessageOut(_connection, mb, _number); _connection->send(message); } diff --git a/Networking/BLIP/Message.hh b/Networking/BLIP/Message.hh index f613e5607..ea9bffbf6 100644 --- a/Networking/BLIP/Message.hh +++ b/Networking/BLIP/Message.hh @@ -193,7 +193,7 @@ namespace litecore::blip { void readFrame(Codec&, int mode, fleece::slice_istream& frame, bool finalFrame); void acknowledge(uint32_t frameSize); - Retained _connection; // The owning BLIP connection + fleece::Ref _connection; // The owning BLIP connection mutable std::mutex _receiveMutex; MessageSize _rawBytesReceived{0}; std::unique_ptr _in; // Accumulates body data (not JSON) diff --git a/Networking/HTTP/CookieStore.hh b/Networking/HTTP/CookieStore.hh index 28cb04480..d7b0aa962 100644 --- a/Networking/HTTP/CookieStore.hh +++ b/Networking/HTTP/CookieStore.hh @@ -23,7 +23,6 @@ struct C4Address; namespace litecore::net { using fleece::RefCounted; - using fleece::Retained; /** Represents an HTTP cookie. */ struct Cookie { diff --git a/Networking/TLSContext.cc b/Networking/TLSContext.cc index 846b95dbb..6dcd312c6 100644 --- a/Networking/TLSContext.cc +++ b/Networking/TLSContext.cc @@ -66,7 +66,7 @@ namespace litecore::net { #ifdef ROOT_CERT_LOOKUP_AVAILABLE bool TLSContext::findSigningRootCert(const string& certStr, string& rootStr) { try { - Retained cert = new Cert(certStr); + Ref cert = new Cert(certStr); Retained root = cert->findSigningRootCert(); if ( root ) rootStr = string(root->dataOfChain()); return true; @@ -104,7 +104,7 @@ namespace litecore::net { }); _context->set_auth_callback([](const string& certData) { - Retained cert = new Cert(slice(certData)); + Ref cert = new Cert(slice(certData)); return cert->isSelfSigned(); }); } else { diff --git a/Networking/WebSockets/BuiltInWebSocket.cc b/Networking/WebSockets/BuiltInWebSocket.cc index 640423713..9feb6e614 100644 --- a/Networking/WebSockets/BuiltInWebSocket.cc +++ b/Networking/WebSockets/BuiltInWebSocket.cc @@ -95,7 +95,7 @@ namespace litecore::websocket { // This runs on its own thread. void BuiltInWebSocket::_bgConnect() { - Retained temporarySelfRetain = this; + Ref temporarySelfRetain = this; setThreadName(); if ( _socket ) { @@ -292,7 +292,7 @@ namespace litecore::websocket { } #ifdef COUCHBASE_ENTERPRISE if ( parameters().externalKey ) { - Retained cert = make_retained(certData); + Ref cert = make_retained(certData); _tlsContext->setIdentity(new crypto::Identity(cert, parameters().externalKey->getPrivateKey())); return true; } @@ -302,7 +302,7 @@ namespace litecore::websocket { return true; } else { #ifdef PERSISTENT_PRIVATE_KEY_AVAILABLE - Retained cert = new crypto::Cert(certData); + Ref cert = new crypto::Cert(certData); Retained key = cert->loadPrivateKey(); if ( !key ) { closeWithError(c4error_make(LiteCoreDomain, kC4ErrorCrypto, diff --git a/Networking/WebSockets/WebSocketImpl.cc b/Networking/WebSockets/WebSocketImpl.cc index 82359a333..2eae0dc3d 100644 --- a/Networking/WebSockets/WebSocketImpl.cc +++ b/Networking/WebSockets/WebSocketImpl.cc @@ -263,7 +263,7 @@ namespace litecore::websocket { void WebSocketImpl::deliverMessageToDelegate(slice data, bool /*binary*/) { logVerbose("Received %zu-byte message", data.size); _deliveredBytes += data.size; - Retained message(new MessageImpl(this, data, true)); + Ref message(new MessageImpl(this, data, true)); delegateWeak()->invoke(&Delegate::onWebSocketMessage, message); } diff --git a/Networking/WebSockets/WebSocketInterface.cc b/Networking/WebSockets/WebSocketInterface.cc index 778587712..7df303c37 100644 --- a/Networking/WebSockets/WebSocketInterface.cc +++ b/Networking/WebSockets/WebSocketInterface.cc @@ -34,8 +34,7 @@ namespace litecore::websocket { void WebSocket::connect(Retained> weakDelegate) { DebugAssert(!_delegateWeakHolder); - // Clang-Tidy suggests std::move, but it breaks the retain - _delegateWeakHolder = weakDelegate; // NOLINT(performance-unnecessary-value-param) + _delegateWeakHolder = std::move(weakDelegate); connect(); } diff --git a/REST/Response.cc b/REST/Response.cc index 61e9bf409..a6cb3d5b2 100644 --- a/REST/Response.cc +++ b/REST/Response.cc @@ -117,7 +117,7 @@ namespace litecore::REST { Response& Response::setIdentity(C4Cert* cert, C4KeyPair* key) { Assert(key->hasPrivateKey()); - Retained id = new Identity(cert->assertSignedCert(), key->getPrivateKey()); + Ref id = new Identity(cert->assertSignedCert(), key->getPrivateKey()); tlsContext()->setIdentity(id); return *this; } diff --git a/Replicator/ChangesFeed.cc b/Replicator/ChangesFeed.cc index 1d784b2c3..0e761ae13 100644 --- a/Replicator/ChangesFeed.cc +++ b/Replicator/ChangesFeed.cc @@ -104,7 +104,7 @@ namespace litecore::repl { C4DocumentInfo info = e.documentInfo(); auto rev = makeRevToSend(info, &e); if ( rev ) { - changes.revs.push_back(rev); + changes.revs.push_back(rev.asRef()); --limit; } } @@ -167,7 +167,7 @@ namespace litecore::repl { break; } } - changes.revs.push_back(rev); + changes.revs.push_back(rev.asRef()); --limit; } } diff --git a/Replicator/DBAccess.hh b/Replicator/DBAccess.hh index b7de8b302..7c49ba1d6 100644 --- a/Replicator/DBAccess.hh +++ b/Replicator/DBAccess.hh @@ -30,6 +30,7 @@ #include namespace litecore::repl { + using fleece::Ref; using fleece::Retained; class ReplicatedRev; class UseCollection; @@ -170,7 +171,7 @@ namespace litecore::repl { fleece::SharedKeys tempSharedKeys(); fleece::SharedKeys updateTempSharedKeys(); - Retained _pool; // Pool of C4Databases + Ref _pool; // Pool of C4Databases C4BlobStore* _blobStore{}; // Database's BlobStore fleece::SharedKeys _tempSharedKeys; // Keys used in tempEncodeJSON() std::mutex _tempSharedKeysMutex; // Mutex for replacing _tempSharedKeys diff --git a/Replicator/IncomingRev.cc b/Replicator/IncomingRev.cc index e1542184a..f70ed5bea 100644 --- a/Replicator/IncomingRev.cc +++ b/Replicator/IncomingRev.cc @@ -404,7 +404,7 @@ namespace litecore::repl { // Called directly by the Inserter, on its thread, after the revision is safely committed to disk. void IncomingRev::revisionInserted() { - Retained retainSelf = this; + Ref retainSelf = this; decrement(_pendingCallbacks); finish(); } diff --git a/Replicator/IncomingRev.hh b/Replicator/IncomingRev.hh index 9163705cd..eb2853a9b 100644 --- a/Replicator/IncomingRev.hh +++ b/Replicator/IncomingRev.hh @@ -55,7 +55,7 @@ namespace litecore::repl { private: void reinitialize(); void parseAndInsert(alloc_slice jsonBody); - void _handleRev(Retained); + void _handleRev(Ref); void gotDeltaSrc(alloc_slice deltaSrcBody); fleece::Doc parseBody(alloc_slice jsonBody); void processFleeceBody(fleece::Doc); diff --git a/Replicator/Puller.cc b/Replicator/Puller.cc index dfcb50a6e..30ed1614c 100644 --- a/Replicator/Puller.cc +++ b/Replicator/Puller.cc @@ -143,7 +143,7 @@ namespace litecore::repl { } // We lost access to some documents; they need to be purged locally. - void Puller::_documentsRevoked(std::vector> revs) { + void Puller::_documentsRevoked(std::vector> revs) { for ( auto& rev : revs ) { if ( _activeIncomingRevoked < tuning::kMaxActiveIncomingRevs && _unfinishedIncomingRevoked < tuning::kMaxIncomingRevs ) { @@ -158,7 +158,7 @@ namespace litecore::repl { } // Received an incoming "rev" message, which contains a revision body to insert - void Puller::handleRev(Retained msg) { + void Puller::handleRev(Ref msg) { if ( _activeIncomingRevs < tuning::kMaxActiveIncomingRevs && _unfinishedIncomingRevs < tuning::kMaxIncomingRevs ) { startIncomingRev(msg); @@ -174,7 +174,7 @@ namespace litecore::repl { } // Received an incoming "norev" message, which means the peer was unable to send a revision - void Puller::handleNoRev(Retained msg) { + void Puller::handleNoRev(Ref msg) { _revFinder->revReceived(); decrement(_pendingRevMessages); slice sequence(msg->property("sequence"_sl)); @@ -351,7 +351,7 @@ namespace litecore::repl { #pragma mark - STATUS / PROGRESS: - void Puller::_childChangedStatus(Retained task, Status status) { + void Puller::_childChangedStatus(Ref task, Status status) { // Combine the IncomingRev's progress into mine: addProgress(status.progressDelta); if ( status.error.domain == WebSocketDomain && status.error.code == 503 ) { @@ -441,7 +441,7 @@ namespace litecore::repl { _activeIncomingRevs, _waitingRevMessages.size(), _unfinishedIncomingRevs); } - if ( level == kC4Stopped ) _revFinder = nullptr; // break cycle + if ( level == kC4Stopped ) std::move(_revFinder).destroy(); // break cycle return level; } diff --git a/Replicator/Puller.hh b/Replicator/Puller.hh index 358f764e6..a7f701861 100644 --- a/Replicator/Puller.hh +++ b/Replicator/Puller.hh @@ -63,20 +63,20 @@ namespace litecore::repl { enqueue(FUNCTION_TO_QUEUE(Puller::_expectSequences), std::move(changes)); } - void documentsRevoked(std::vector> revs) override { + void documentsRevoked(std::vector> revs) override { enqueue(FUNCTION_TO_QUEUE(Puller::_documentsRevoked), std::move(revs)); } - void _childChangedStatus(Retained, Status) override; + void _childChangedStatus(Ref, Status) override; ActivityLevel computeActivityLevel(std::string* reason) const override; void activityLevelChanged(ActivityLevel level); private: void _start(RemoteSequence sinceSequence); void _expectSequences(std::vector); - void _documentsRevoked(std::vector>); - void handleRev(Retained); - void handleNoRev(Retained); + void _documentsRevoked(std::vector>); + void handleRev(Ref); + void handleNoRev(Ref); template Retained makeIncomingRev(); void startIncomingRev(blip::MessageIn* NONNULL); @@ -97,13 +97,13 @@ namespace litecore::repl { bool _caughtUp{false}; // Got all historic sequences, now up to date bool _fatalError{false}; // Have I gotten a fatal error? - RemoteSequenceSet _missingSequences; // Known sequences I need to pull - std::deque> _waitingRevMessages; // Queued 'rev' messages - std::deque> _waitingRevoked; // Queued revoked docs - mutable std::vector> _spareIncomingRevs; // Cache of IncomingRevs - actor::ActorCountBatcher _provisionallyHandledRevs; - actor::ActorCountBatcher _provisionallyHandledRevoked; - actor::ActorBatcher _returningRevs; + RemoteSequenceSet _missingSequences; // Known sequences I need to pull + std::deque> _waitingRevMessages; // Queued 'rev' messages + std::deque> _waitingRevoked; // Queued revoked docs + mutable std::vector> _spareIncomingRevs; // Cache of IncomingRevs + actor::ActorCountBatcher _provisionallyHandledRevs; + actor::ActorCountBatcher _provisionallyHandledRevoked; + actor::ActorBatcher _returningRevs; #if __APPLE__ // This helps limit the number of threads used by GCD: actor::Mailbox* mailboxForChildren() override { return &_revMailbox; } @@ -112,13 +112,13 @@ namespace litecore::repl { // call this->mailboxForChildren() which depends on it. actor::Mailbox _revMailbox; #endif - Retained _inserter; - mutable Retained _revFinder; - unsigned _pendingRevMessages{0}; // # of 'rev' msgs expected but not yet being processed - unsigned _activeIncomingRevs{0}; // # of IncomingRev workers running for revs - unsigned _activeIncomingRevoked{0}; // # of IncomingRev workers running for revoked docs - unsigned _unfinishedIncomingRevs{0}; - unsigned _unfinishedIncomingRevoked{0}; + Ref _inserter; + mutable Ref _revFinder; + unsigned _pendingRevMessages{0}; // # of 'rev' msgs expected but not yet being processed + unsigned _activeIncomingRevs{0}; // # of IncomingRev workers running for revs + unsigned _activeIncomingRevoked{0}; // # of IncomingRev workers running for revoked docs + unsigned _unfinishedIncomingRevs{0}; + unsigned _unfinishedIncomingRevoked{0}; }; diff --git a/Replicator/Pusher+Attachments.cc b/Replicator/Pusher+Attachments.cc index 35fec21b8..b9a80bf41 100644 --- a/Replicator/Pusher+Attachments.cc +++ b/Replicator/Pusher+Attachments.cc @@ -60,7 +60,7 @@ namespace litecore::repl { private: Pusher* _pusher; - Retained _repl; + Ref _repl; unique_ptr _blob; Replicator::BlobProgress _progress; actor::Timer::clock::time_point _lastNotifyTime = actor::Timer::clock::now(); @@ -87,7 +87,7 @@ namespace litecore::repl { } // Incoming request to send an attachment/blob - void Pusher::handleGetAttachment(Retained req) { + void Pusher::handleGetAttachment(Ref req) { slice digest; Replicator::BlobProgress progress; unique_ptr blob = readBlobFromRequest(req, digest, progress); @@ -98,7 +98,7 @@ namespace litecore::repl { reply.compressed = req->boolProperty("compress"_sl); logVerbose("Sending blob %.*s (length=%" PRIu64 ", compress=%d)", SPLAT(digest), blob->getLength(), reply.compressed); - Retained repl = replicator(); + Ref repl = replicator(); auto collIndex = Worker::getCollectionIndex(*req); if ( collIndex != kNotCollectionIndex ) { @@ -115,7 +115,7 @@ namespace litecore::repl { void Pusher::_attachmentSent() { decrement(_blobsInFlight); } // Incoming request to prove I have an attachment that I'm pushing, without sending it: - void Pusher::handleProveAttachment(Retained request) { + void Pusher::handleProveAttachment(Ref request) { slice digest; Replicator::BlobProgress progress; unique_ptr blob = readBlobFromRequest(request, digest, progress); diff --git a/Replicator/Pusher+Revs.cc b/Replicator/Pusher+Revs.cc index a9d785c3b..4926e5221 100644 --- a/Replicator/Pusher+Revs.cc +++ b/Replicator/Pusher+Revs.cc @@ -65,7 +65,7 @@ namespace litecore::repl { void Pusher::maybeSendMoreRevs() { while ( _revisionsInFlight < tuning::kMaxRevsInFlight && _revisionBytesAwaitingReply <= tuning::kMaxRevBytesAwaitingReply && !_revQueue.empty() ) { - Retained first = std::move(_revQueue.front()); + Ref first = std::move(_revQueue.front()); _revQueue.pop_front(); sendRevision(first); if ( _revQueue.size() == tuning::kMaxRevsQueued - 1 ) @@ -78,7 +78,7 @@ namespace litecore::repl { } // Send a "rev" message containing a revision body. - void Pusher::sendRevision(Retained request) { + void Pusher::sendRevision(Ref request) { if ( !connected() ) return; logVerbose("Sending rev '%.*s' #%.*s (seq #%" PRIu64 ") [%u/%u]", SPLAT(request->docID), SPLAT(request->revID), @@ -235,7 +235,7 @@ namespace litecore::repl { } // "rev" message progress callback: - void Pusher::onRevProgress(const Retained& rev, const MessageProgress& progress) { + void Pusher::onRevProgress(const Ref& rev, const MessageProgress& progress) { switch ( progress.state ) { case MessageProgress::kDisconnected: doneWithRev(rev, false, false); diff --git a/Replicator/Pusher.cc b/Replicator/Pusher.cc index 4cb7e13d9..4f1d83963 100644 --- a/Replicator/Pusher.cc +++ b/Replicator/Pusher.cc @@ -55,7 +55,7 @@ namespace litecore::repl { } // Handles an incoming "subChanges" message: starts passive push (i.e. the peer is pulling). - void Pusher::handleSubChanges(Retained req) { + void Pusher::handleSubChanges(Ref req) { if ( !passive() ) { warn("Ignoring 'subChanges' request from peer; I'm already pushing"); req->respondWithError({"LiteCore"_sl, 501, "Not implemented."_sl}); @@ -470,7 +470,7 @@ namespace litecore::repl { if ( i != _conflictsIMightRetry.end() ) { // OK, this is a potential conflict I noted in shouldRetryConflictWithNewerAncestor(). // See if the doc is unchanged, by getting it by sequence: - Retained rev = i->second; + Ref rev = i->second; _conflictsIMightRetry.erase(i); auto coll = _db->useCollection(collectionSpec()); Retained doc = coll->getDocumentBySequence(rev->sequence); diff --git a/Replicator/Pusher.hh b/Replicator/Pusher.hh index 9237724f9..88f6c1472 100644 --- a/Replicator/Pusher.hh +++ b/Replicator/Pusher.hh @@ -67,7 +67,7 @@ namespace litecore::repl { void _start(); bool isBusy(std::string* reason = nullptr) const; void startSending(C4SequenceNumber sinceSequence); - void handleSubChanges(Retained req); + void handleSubChanges(Ref req); void gotOutOfOrderChange(RevToSend* NONNULL); void encodeRevID(Encoder& enc, slice revID); void sendChanges(RevToSendList&); @@ -88,44 +88,44 @@ namespace litecore::repl { bool getForeignAncestors() const { return _proposeChanges || !_proposeChangesKnown; } // Pusher+Attachments.cc: - void handleGetAttachment(Retained); - void handleProveAttachment(Retained); + void handleGetAttachment(Ref); + void handleProveAttachment(Ref); void _attachmentSent(); unique_ptr readBlobFromRequest(blip::MessageIn* req NONNULL, slice& outDigest, Replicator::BlobProgress& outProgress); // Pusher+Revs.cc: void maybeSendMoreRevs(); void retryRevs(RevToSendList, bool immediate); - void sendRevision(Retained); - void onRevProgress(const Retained& rev, const blip::MessageProgress&); + void sendRevision(Ref); + void onRevProgress(const Ref& rev, const blip::MessageProgress&); void couldntSendRevision(RevToSend* NONNULL); void doneWithRev(RevToSend*, bool successful, bool pushed); alloc_slice createRevisionDelta(C4Document* doc NONNULL, RevToSend* request NONNULL, fleece::Dict root, size_t revSize, bool sendLegacyAttachments); void revToSendIsObsolete(const RevToSend& request, C4Error* c4err = nullptr); - using DocIDToRevMap = std::unordered_map>; - - bool _continuous; - bool _proposeChanges; - bool _proposeChangesKnown; - ReplicatorChangesFeed _changesFeed; - DocIDToRevMap _pushingDocs; // Revs being processed by push - DocIDToRevMap _conflictsIMightRetry; - C4SequenceNumber _lastSequenceRead{0}; // Last sequence read from db - C4SequenceNumber _lastSequenceLogged{0}; // Checkpointed last-sequence - Checkpointer& _checkpointer; // Tracks checkpoints & pending sequences - bool _started{false}; - bool _caughtUp{false}; // Received backlog of pre-existing changes? - bool _continuousCaughtUp{true}; // Caught up with change notifications? - bool _deltasOK{false}; // OK to send revs in delta form? - bool _sendReplacementRevs{false}; - unsigned _changeListsInFlight{0}; // # change lists being requested from db or sent to peer - unsigned _revisionsInFlight{0}; // # 'rev' messages being sent - blip::MessageSize _revisionBytesAwaitingReply{0}; // # 'rev' message bytes sent but not replied - unsigned _blobsInFlight{0}; // # of blobs being sent - std::deque> _revQueue; // Revs to send to peer but not sent yet - RevToSendList _revsToRetry; // Revs that failed with a transient error + using DocIDToRevMap = std::unordered_map>; + + bool _continuous; + bool _proposeChanges; + bool _proposeChangesKnown; + ReplicatorChangesFeed _changesFeed; + DocIDToRevMap _pushingDocs; // Revs being processed by push + DocIDToRevMap _conflictsIMightRetry; + C4SequenceNumber _lastSequenceRead{0}; // Last sequence read from db + C4SequenceNumber _lastSequenceLogged{0}; // Checkpointed last-sequence + Checkpointer& _checkpointer; // Tracks checkpoints & pending sequences + bool _started{false}; + bool _caughtUp{false}; // Received backlog of pre-existing changes? + bool _continuousCaughtUp{true}; // Caught up with change notifications? + bool _deltasOK{false}; // OK to send revs in delta form? + bool _sendReplacementRevs{false}; + unsigned _changeListsInFlight{0}; // # change lists being requested from db or sent to peer + unsigned _revisionsInFlight{0}; // # 'rev' messages being sent + blip::MessageSize _revisionBytesAwaitingReply{0}; // # 'rev' message bytes sent but not replied + unsigned _blobsInFlight{0}; // # of blobs being sent + std::deque> _revQueue; // Revs to send to peer but not sent yet + RevToSendList _revsToRetry; // Revs that failed with a transient error }; diff --git a/Replicator/Replicator.cc b/Replicator/Replicator.cc index f4546d471..0dc4a7b8e 100644 --- a/Replicator/Replicator.cc +++ b/Replicator/Replicator.cc @@ -273,7 +273,7 @@ namespace litecore::repl { if ( pusher ) pusher->docRemoteAncestorChanged(std::move(docID), std::move(revID)); } - void Replicator::returnForbidden(Retained request) { + void Replicator::returnForbidden(Ref request) { auto collectionIn = request->intProperty(kCollectionProperty, kNotCollectionIndex); CollectionIndex c = 0; if ( collectionIn != kNotCollectionIndex ) { @@ -373,7 +373,7 @@ namespace litecore::repl { } // The status of one of the actors has changed; update mine - void Replicator::_childChangedStatus(Retained task, Status taskStatus) { + void Replicator::_childChangedStatus(Ref task, Status taskStatus) { if ( status().level == kC4Stopped ) // I've already stopped & cleared refs; ignore this return; @@ -689,7 +689,7 @@ namespace litecore::repl { } // This only gets called if none of the registered handlers were triggered. - void Replicator::_onRequestReceived(Retained msg) { + void Replicator::_onRequestReceived(Ref msg) { auto collection = (CollectionIndex)msg->intProperty(kCollectionProperty, kNotCollectionIndex); if ( collection == kNotCollectionIndex ) warn("Received unrecognized BLIP request #%" PRIu64 "(collection: none) with Profile '%.*s', %zu bytes", @@ -1032,7 +1032,7 @@ namespace litecore::repl { } // Handles a "getCheckpoint" request by looking up a peer checkpoint. - void Replicator::handleGetCheckpoint(Retained request) { + void Replicator::handleGetCheckpoint(Ref request) { slice checkpointID = getPeerCheckpointDocID(request, "get"); if ( !checkpointID ) return; @@ -1068,7 +1068,7 @@ namespace litecore::repl { } // Handles a "setCheckpoint" request by storing a peer checkpoint. - void Replicator::handleSetCheckpoint(Retained request) { + void Replicator::handleSetCheckpoint(Ref request) { slice checkpointID = getPeerCheckpointDocID(request, "set"); if ( !checkpointID ) return; @@ -1102,7 +1102,7 @@ namespace litecore::repl { } // Handles a "getCollections" request by looking up a peer checkpoint of each collection. - void Replicator::handleGetCollections(Retained request) { + void Replicator::handleGetCollections(Ref request) { // This message only comes from 3.1+ client. if ( !_subRepls.empty() ) { @@ -1279,7 +1279,7 @@ namespace litecore::repl { logVerbose("Remote-DB ID %u found for target <%.*s>", remoteDBID, SPLAT(key)); } - void Replicator::delegateCollectionSpecificMessageToWorker(Retained request) { + void Replicator::delegateCollectionSpecificMessageToWorker(Ref request) { // This method is NOT called on the Replicator's queue/thread! It must be thread-safe. slice profile = request->property("Profile"_sl); diff --git a/Replicator/Replicator.hh b/Replicator/Replicator.hh index af52915af..c803dd2ed 100644 --- a/Replicator/Replicator.hh +++ b/Replicator/Replicator.hh @@ -61,7 +61,7 @@ namespace litecore::repl { C4Error error; }; - using DocumentsEnded = std::vector>; + using DocumentsEnded = std::vector>; /// A list of WebSocket subprotocol names supported by a Replicator with the given Options. static std::vector compatibleProtocols(C4DatabaseFlags, Options::Mode pushMode, Options::Mode pullMode); @@ -144,7 +144,7 @@ namespace litecore::repl { } void onRequestReceived(blip::MessageIn* msg NONNULL) override { - enqueue(FUNCTION_TO_QUEUE(Replicator::_onRequestReceived), retained(msg)); + enqueue(FUNCTION_TO_QUEUE(Replicator::_onRequestReceived), retainedRef(msg)); } void changedStatus() override; @@ -153,14 +153,14 @@ namespace litecore::repl { // Worker method overrides: ActivityLevel computeActivityLevel(std::string* reason) const override; - void _childChangedStatus(Retained, Status taskStatus) override; + void _childChangedStatus(Ref, Status taskStatus) override; private: void _onHTTPResponse(int status, websocket::Headers headers); void _onConnect(); void _onError(int errcode, fleece::alloc_slice reason); void _onClose(CloseStatus, blip::Connection::State); - void _onRequestReceived(Retained msg); + void _onRequestReceived(Ref msg); void _start(bool reset); void _stop(); @@ -187,10 +187,10 @@ namespace litecore::repl { // Checkpoints: void checkpointIsInvalid(); std::string remoteDBIDString() const; - void handleGetCheckpoint(Retained); - void handleSetCheckpoint(Retained); - void handleGetCollections(Retained); - void returnForbidden(Retained); + void handleGetCheckpoint(Ref); + void handleSetCheckpoint(Ref); + void handleGetCollections(Ref); + void returnForbidden(Ref); slice getPeerCheckpointDocID(blip::MessageIn* request, const char* whatFor) const; string statusVString() const; @@ -198,14 +198,14 @@ namespace litecore::repl { void updatePullStatus(CollectionIndex i, const Status& status); void prepareWorkers(); - void delegateCollectionSpecificMessageToWorker(Retained); + void delegateCollectionSpecificMessageToWorker(Ref); public: - using WorkerHandler = std::function)>; + using WorkerHandler = std::function)>; template void registerWorkerHandler(WORKER* worker, const char* profile NONNULL, - void (WORKER::*method)(Retained)) { + void (WORKER::*method)(Ref)) { WorkerHandler fn(std::bind(method, worker, std::placeholders::_1)); pair key{profile, worker->collectionIndex()}; _workerHandlers.useLocked()->emplace(key, worker->asynchronize(profile, fn)); diff --git a/Replicator/ReplicatorTypes.hh b/Replicator/ReplicatorTypes.hh index 9e1383109..1a6b80d91 100644 --- a/Replicator/ReplicatorTypes.hh +++ b/Replicator/ReplicatorTypes.hh @@ -22,6 +22,7 @@ struct C4DocumentInfo; namespace litecore::repl { + using fleece::Ref; using fleece::RefCounted; using fleece::Retained; using fleece::RetainedConst; @@ -80,7 +81,7 @@ namespace litecore::repl { ~RevToSend() override = default; }; - typedef std::vector> RevToSendList; + typedef std::vector> RevToSendList; /** A revision to be added to the database, complete with body. */ class RevToInsert final : public ReplicatedRev { diff --git a/Replicator/RevFinder.cc b/Replicator/RevFinder.cc index fc7ba75f5..bbda1d3a1 100644 --- a/Replicator/RevFinder.cc +++ b/Replicator/RevFinder.cc @@ -46,7 +46,7 @@ namespace litecore::repl { } // Receiving an incoming "changes" (or "proposeChanges") message - void RevFinder::handleChanges(Retained req) { + void RevFinder::handleChanges(Ref req) { if ( pullerHasCapacity() ) { handleChangesNow(req); } else { @@ -182,10 +182,10 @@ namespace litecore::repl { // adds each entry to `sequences`, and returns the number of new revs. unsigned RevFinder::findRevs(Array changes, JSONEncoder& encoder, vector& sequences) { // Compile the docIDs/revIDs into parallel vectors: - vector docIDs, revIDs; - vector> revoked; - vector changeIndexes; - auto nChanges = changes.count(); + vector docIDs, revIDs; + vector> revoked; + vector changeIndexes; + auto nChanges = changes.count(); docIDs.reserve(nChanges); revIDs.reserve(nChanges); uint32_t changeIndex = 0; diff --git a/Replicator/RevFinder.hh b/Replicator/RevFinder.hh index ff7f2859e..1ce2a00e2 100644 --- a/Replicator/RevFinder.hh +++ b/Replicator/RevFinder.hh @@ -41,7 +41,7 @@ namespace litecore::repl { /** Tells the Delegate about the "rev" messages it will be receiving. */ virtual void expectSequences(std::vector) = 0; /** These document(s) are no longer accessible on the server and should be purged. */ - virtual void documentsRevoked(std::vector>) = 0; + virtual void documentsRevoked(std::vector>) = 0; }; RevFinder(Replicator* NONNULL, Delegate* NONNULL, CollectionIndex); @@ -69,7 +69,7 @@ namespace litecore::repl { return _numRevsBeingRequested + _numRevokedBeingHandled <= tuning::kMaxRevsBeingRequested; } - void handleChanges(Retained); + void handleChanges(Ref); void handleMoreChanges(); void handleChangesNow(blip::MessageIn* req); @@ -81,12 +81,12 @@ namespace litecore::repl { void _reRequestingRev(); void checkDocAndRevID(slice docID, slice revID); - Retained _delegate; - std::deque> _waitingChangesMessages; // Queued 'changes' messages - unsigned _numRevsBeingRequested{0}; // # of 'rev' msgs requested but not yet received - unsigned _numRevokedBeingHandled{0}; // # of revoked docs currently being processed - bool _announcedDeltaSupport{false}; // Did I send "deltas:true" yet? - bool _mustBeProposed{false}; // Do I handle only "proposedChanges"? + Retained _delegate; + std::deque> _waitingChangesMessages; // Queued 'changes' messages + unsigned _numRevsBeingRequested{0}; // # of 'rev' msgs requested but not yet received + unsigned _numRevokedBeingHandled{0}; // # of revoked docs currently being processed + bool _announcedDeltaSupport{false}; // Did I send "deltas:true" yet? + bool _mustBeProposed{false}; // Do I handle only "proposedChanges"? #ifdef LITECORE_CPPTEST public: bool _disableReplacementRevs{false}; diff --git a/Replicator/Worker.cc b/Replicator/Worker.cc index efcd3969c..ceb9bcb40 100644 --- a/Replicator/Worker.cc +++ b/Replicator/Worker.cc @@ -204,11 +204,7 @@ namespace litecore::repl { return parent->replicatorIfAny(); } - Retained Worker::replicator() { - auto replicator = replicatorIfAny(); - Assert(replicator != nullptr); - return replicator; - } + Ref Worker::replicator() { return replicatorIfAny().asRef(); } void Worker::finishedDocumentWithError(ReplicatedRev* rev, C4Error error, bool transient) { rev->error = error; diff --git a/Replicator/Worker.hh b/Replicator/Worker.hh index a247deb39..3b99787d9 100644 --- a/Replicator/Worker.hh +++ b/Replicator/Worker.hh @@ -69,7 +69,7 @@ namespace litecore::repl { /// The Replicator at the top of the tree. Never NULL. /// @warning Throws rather than returning NULL. - Retained replicator(); + Ref replicator(); /// True if the replicator is passive (run by the listener.) virtual bool passive() const { return false; } @@ -79,7 +79,7 @@ namespace litecore::repl { /// Child workers call this on their parent when their status changes. void childChangedStatus(Worker* task, const Status& status) { - enqueue(FUNCTION_TO_QUEUE(Worker::_childChangedStatus), Retained(task), status); + enqueue(FUNCTION_TO_QUEUE(Worker::_childChangedStatus), Ref(task), status); } C4ReplicatorProgressLevel progressNotificationLevel() const { return _options->progressLevel; } @@ -169,8 +169,8 @@ namespace litecore::repl { /// Registers a method to run when a BLIP request with the given profile arrives. template - void registerHandler(const char* profile NONNULL, void (ACTOR::*method)(Retained)) { - std::function)> fn(std::bind(method, (ACTOR*)this, std::placeholders::_1)); + void registerHandler(const char* profile NONNULL, void (ACTOR::*method)(Ref)) { + std::function)> fn(std::bind(method, (ACTOR*)this, std::placeholders::_1)); _connection->setRequestHandler(profile, false, asynchronize(profile, fn)); } @@ -211,7 +211,7 @@ namespace litecore::repl { /// Implementation of public `childChangedStatus`; called on this Actor's thread. /// Does nothing, but you can override. - virtual void _childChangedStatus(Retained task, Status) {} + virtual void _childChangedStatus(Ref task, Status) {} /// Adds the counts in the given struct to my status's progress. void addProgress(C4Progress); diff --git a/Replicator/c4Replicator+Pool.hh b/Replicator/c4Replicator+Pool.hh index 678b6f75d..db8d55687 100644 --- a/Replicator/c4Replicator+Pool.hh +++ b/Replicator/c4Replicator+Pool.hh @@ -26,15 +26,14 @@ namespace litecore { // C4Replicator factory functions that take a DatabasePool instead of a C4Database. -fleece::Retained NewReplicator(litecore::DatabasePool* dbPool, C4Address serverAddress, - fleece::slice remoteDatabaseName, const C4ReplicatorParameters& params, - fleece::slice logPrefix = {}); -fleece::Retained NewLocalReplicator(litecore::DatabasePool* dbPool, litecore::DatabasePool* otherLocalDB, - const C4ReplicatorParameters& params, fleece::slice logPrefix = {}); -fleece::Retained NewIncomingReplicator(litecore::DatabasePool* dbPool, - litecore::websocket::WebSocket* openSocket, - const C4ReplicatorParameters& params, - fleece::slice logPrefix = {}); +fleece::Ref NewReplicator(litecore::DatabasePool* dbPool, C4Address serverAddress, + fleece::slice remoteDatabaseName, const C4ReplicatorParameters& params, + fleece::slice logPrefix = {}); +fleece::Ref NewLocalReplicator(litecore::DatabasePool* dbPool, litecore::DatabasePool* otherLocalDB, + const C4ReplicatorParameters& params, fleece::slice logPrefix = {}); +fleece::Ref NewIncomingReplicator(litecore::DatabasePool* dbPool, + litecore::websocket::WebSocket* openSocket, + const C4ReplicatorParameters& params, fleece::slice logPrefix = {}); C4_ASSUME_NONNULL_END diff --git a/Replicator/c4Replicator.cc b/Replicator/c4Replicator.cc index 7763d8530..aa35f93c1 100644 --- a/Replicator/c4Replicator.cc +++ b/Replicator/c4Replicator.cc @@ -30,8 +30,8 @@ using namespace litecore; #pragma mark - C4DATABASE METHODS: -static Retained newRemoteReplicator(DatabaseOrPool db, C4Address serverAddress, slice remoteDatabaseName, - const C4ReplicatorParameters& params, slice logPrefix) { +static Ref newRemoteReplicator(DatabaseOrPool db, C4Address serverAddress, slice remoteDatabaseName, + const C4ReplicatorParameters& params, slice logPrefix) { if ( !params.socketFactory ) { C4Replicator::validateRemote(serverAddress, remoteDatabaseName); if ( serverAddress.port == 4985 && serverAddress.hostname != "localhost"_sl ) { @@ -43,20 +43,20 @@ static Retained newRemoteReplicator(DatabaseOrPool db, C4Address s return new C4RemoteReplicator(std::move(db), params, serverAddress, remoteDatabaseName, logPrefix); } -Retained C4Database::newReplicator(C4Address serverAddress, slice remoteDatabaseName, - const C4ReplicatorParameters& params, slice logPrefix) { +Ref C4Database::newReplicator(C4Address serverAddress, slice remoteDatabaseName, + const C4ReplicatorParameters& params, slice logPrefix) { return newRemoteReplicator(this, serverAddress, remoteDatabaseName, params, logPrefix); } -Retained NewReplicator(DatabasePool* dbPool, C4Address serverAddress, slice remoteDatabaseName, - const C4ReplicatorParameters& params, slice logPrefix) { +Ref NewReplicator(DatabasePool* dbPool, C4Address serverAddress, slice remoteDatabaseName, + const C4ReplicatorParameters& params, slice logPrefix) { return newRemoteReplicator(dbPool, serverAddress, remoteDatabaseName, params, logPrefix); } #ifdef COUCHBASE_ENTERPRISE -static Retained _newLocalReplicator(DatabaseOrPool db, DatabaseOrPool otherDB, - const C4ReplicatorParameters& params, slice logPrefix) { +static Ref _newLocalReplicator(DatabaseOrPool db, DatabaseOrPool otherDB, + const C4ReplicatorParameters& params, slice logPrefix) { std::for_each(params.collections, params.collections + params.collectionCount, [](const C4ReplicationCollection& coll) { AssertParam(coll.push != kC4Disabled || coll.pull != kC4Disabled, @@ -66,29 +66,29 @@ static Retained _newLocalReplicator(DatabaseOrPool db, DatabaseOrP return new C4LocalReplicator(db, params, otherDB, logPrefix); } -Retained C4Database::newLocalReplicator(C4Database* otherLocalDB, const C4ReplicatorParameters& params, - slice logPrefix) { +Ref C4Database::newLocalReplicator(C4Database* otherLocalDB, const C4ReplicatorParameters& params, + slice logPrefix) { return _newLocalReplicator(this, otherLocalDB, params, logPrefix); } -Retained NewLocalReplicator(DatabasePool* dbPool, DatabasePool* otherLocalDB, - const C4ReplicatorParameters& params, slice logPrefix) { +Ref NewLocalReplicator(DatabasePool* dbPool, DatabasePool* otherLocalDB, + const C4ReplicatorParameters& params, slice logPrefix) { return _newLocalReplicator(dbPool, otherLocalDB, params, logPrefix); } #endif -Retained C4Database::newIncomingReplicator(WebSocket* openSocket, const C4ReplicatorParameters& params, - slice logPrefix) { +Ref C4Database::newIncomingReplicator(WebSocket* openSocket, const C4ReplicatorParameters& params, + slice logPrefix) { return new C4IncomingReplicator(this, params, openSocket, logPrefix); } -Retained C4Database::newIncomingReplicator(C4Socket* openSocket, const C4ReplicatorParameters& params, - slice logPrefix) { +Ref C4Database::newIncomingReplicator(C4Socket* openSocket, const C4ReplicatorParameters& params, + slice logPrefix) { return newIncomingReplicator(WebSocketFrom(openSocket), params, logPrefix); } -Retained NewIncomingReplicator(DatabasePool* dbPool, WebSocket* openSocket, - const C4ReplicatorParameters& params, fleece::slice logPrefix) { +Ref NewIncomingReplicator(DatabasePool* dbPool, WebSocket* openSocket, + const C4ReplicatorParameters& params, fleece::slice logPrefix) { return new C4IncomingReplicator(dbPool, params, openSocket, logPrefix); } diff --git a/Replicator/c4ReplicatorImpl.cc b/Replicator/c4ReplicatorImpl.cc index 51908d77b..4b1c72da9 100644 --- a/Replicator/c4ReplicatorImpl.cc +++ b/Replicator/c4ReplicatorImpl.cc @@ -321,7 +321,7 @@ namespace litecore { } void C4ReplicatorImpl::replicatorStatusChanged(Replicator* repl, const Replicator::Status& newStatus) { - Retained selfRetain = this; // Keep myself alive till this method returns + Ref selfRetain = this; // Keep myself alive till this method returns bool stopped, resume = false; { @@ -360,8 +360,7 @@ namespace litecore { // On return from this method, if I stopped I may be deleted (due to clearing _selfRetain) } - void C4ReplicatorImpl::replicatorDocumentsEnded(Replicator* repl, - const std::vector>& revs) { + void C4ReplicatorImpl::replicatorDocumentsEnded(Replicator* repl, const std::vector>& revs) { if ( repl != _replicator ) return; auto nRevs = revs.size(); diff --git a/Replicator/c4ReplicatorImpl.hh b/Replicator/c4ReplicatorImpl.hh index 37ae41f32..5126204d5 100644 --- a/Replicator/c4ReplicatorImpl.hh +++ b/Replicator/c4ReplicatorImpl.hh @@ -131,7 +131,7 @@ namespace litecore { // Replicator::Delegate method, notifying that the status level or progress have changed. void replicatorStatusChanged(Replicator* repl, const Replicator::Status& newStatus) override; // Replicator::Delegate method, notifying that document(s) have finished. - void replicatorDocumentsEnded(Replicator* repl, const std::vector>& revs) override; + void replicatorDocumentsEnded(Replicator* repl, const std::vector>& revs) override; // Replicator::Delegate method, notifying of blob up/download progress. void replicatorBlobProgress(Replicator* repl, const Replicator::BlobProgress& p) override; @@ -149,13 +149,13 @@ namespace litecore { // I will deadlock! void notifyStateChanged() noexcept; - mutable std::mutex _mutex; - DatabaseOrPool const _database; - Retained _options; - Retained _replicator; - C4ReplicatorStatus _status{kC4Stopped}; - bool _activeWhenSuspended{false}; - bool _cancelStop{false}; + mutable std::mutex _mutex; + DatabaseOrPool const _database; + Ref _options; + Retained _replicator; + C4ReplicatorStatus _status{kC4Stopped}; + bool _activeWhenSuspended{false}; + bool _cancelStop{false}; #ifdef COUCHBASE_ENTERPRISE std::shared_ptr _peerTLSCertificateValidator; mutable std::mutex _peerValidatorMutex; diff --git a/Replicator/c4Socket+Internal.hh b/Replicator/c4Socket+Internal.hh index 893df3fb0..70234f17f 100644 --- a/Replicator/c4Socket+Internal.hh +++ b/Replicator/c4Socket+Internal.hh @@ -20,10 +20,9 @@ namespace litecore::repl { class DBAccess; // Main factory function to create a WebSocket. - fleece::Retained CreateWebSocket(const websocket::URL&, const fleece::alloc_slice& options, - std::shared_ptr, const C4SocketFactory*, - void* nativeHandle = nullptr, - C4KeyPair* externalKey = nullptr); + fleece::Ref CreateWebSocket(const websocket::URL&, const fleece::alloc_slice& options, + std::shared_ptr, const C4SocketFactory*, + void* nativeHandle = nullptr, C4KeyPair* externalKey = nullptr); // Returns the WebSocket object associated with a C4Socket websocket::WebSocket* WebSocketFrom(C4Socket* c4sock); diff --git a/Replicator/c4Socket.cc b/Replicator/c4Socket.cc index 599b8d06c..082899dde 100644 --- a/Replicator/c4Socket.cc +++ b/Replicator/c4Socket.cc @@ -62,9 +62,8 @@ namespace litecore::repl { void C4SocketImpl::registerInternalFactory(C4SocketImpl::InternalFactory f) { sRegisteredInternalFactory = f; } - Retained CreateWebSocket(const websocket::URL& url, const alloc_slice& options, - shared_ptr database, const C4SocketFactory* factory, - void* nativeHandle, C4KeyPair* externalKey) { + Ref CreateWebSocket(const websocket::URL& url, const alloc_slice& options, shared_ptr database, + const C4SocketFactory* factory, void* nativeHandle, C4KeyPair* externalKey) { if ( !factory ) factory = sRegisteredFactory; if ( factory ) { diff --git a/Replicator/tests/ReplicatorLoopbackTest.hh b/Replicator/tests/ReplicatorLoopbackTest.hh index 5d19017d1..ecc536255 100644 --- a/Replicator/tests/ReplicatorLoopbackTest.hh +++ b/Replicator/tests/ReplicatorLoopbackTest.hh @@ -363,7 +363,7 @@ class ReplicatorLoopbackTest } } - void replicatorDocumentsEnded(Replicator* repl, const std::vector>& revs) override { + void replicatorDocumentsEnded(Replicator* repl, const std::vector>& revs) override { // Note: Can't use Catch (CHECK, REQUIRE) on a background thread std::unique_lock lock(_mutex); diff --git a/vendor/fleece b/vendor/fleece index 06c87f0e7..e277ef8d8 160000 --- a/vendor/fleece +++ b/vendor/fleece @@ -1 +1 @@ -Subproject commit 06c87f0e7cd88ade6a75a62107a35023f153fd10 +Subproject commit e277ef8d84183fbf4dfef150bb580be68690333a