@@ -98,9 +98,12 @@ using std::nullptr_t;
9898#define SQLITE_ORM_STRUCTURED_BINDINGS_SUPPORTED
9999#endif
100100
101+ #if __cpp_aligned_new >= 201606L
102+ #define SQLITE_ORM_ALIGNED_NEW_SUPPORTED
103+ #endif
104+
101105#if __cpp_generic_lambdas >= 201707L
102106#define SQLITE_ORM_EXPLICIT_GENERIC_LAMBDA_SUPPORTED
103- #else
104107#endif
105108
106109#if __cpp_init_captures >= 201803L
@@ -13887,6 +13890,30 @@ namespace sqlite_orm {
1388713890#include <string> // std::string
1388813891#endif
1388913892
13893+ // #include "functional/cxx_new.h"
13894+
13895+ #ifdef SQLITE_ORM_IMPORT_STD_MODULE
13896+ #include <version>
13897+ #else
13898+ #include <new>
13899+ #endif
13900+
13901+ namespace sqlite_orm {
13902+ namespace internal {
13903+ namespace polyfill {
13904+ #if __cpp_lib_hardware_interference_size >= 201703L
13905+ using std::hardware_constructive_interference_size;
13906+ using std::hardware_destructive_interference_size;
13907+ #else
13908+ constexpr size_t hardware_constructive_interference_size = 64;
13909+ constexpr size_t hardware_destructive_interference_size = 64;
13910+ #endif
13911+ }
13912+ }
13913+
13914+ namespace polyfill = internal::polyfill;
13915+ }
13916+
1389013917// #include "error_code.h"
1389113918
1389213919namespace sqlite_orm {
@@ -13921,8 +13948,8 @@ namespace sqlite_orm {
1392113948 };
1392213949
1392313950 connection_holder(std::string filename, bool openedForeverHint, std::function<void(sqlite3*)> onAfterOpen) :
13924- filename( std::move(filename)), _openedForeverHint{openedForeverHint },
13925- _onAfterOpen{ std::move(onAfterOpen)} {}
13951+ _openedForeverHint{openedForeverHint}, _onAfterOpen{ std::move(onAfterOpen) },
13952+ filename( std::move(filename)) {}
1392613953
1392713954 connection_holder(const connection_holder&) = delete;
1392813955
@@ -13936,7 +13963,7 @@ namespace sqlite_orm {
1393613963 // `maybeLock.isSynced`: the lock above already synchronized everything, so we can just atomically increment the counter
1393713964 // `!maybeLock.isSynced`: we presume that the connection is opened once in a single-threaded context [also open forever].
1393813965 // therefore we can just use an atomic increment but don't need sequencing due to `prevCount > 0`.
13939- if (int prevCount = _retain_count .fetch_add(1, std::memory_order_relaxed); prevCount > 0) {
13966+ if (int prevCount = _retainCount .fetch_add(1, std::memory_order_relaxed); prevCount > 0) {
1394013967 return;
1394113968 }
1394213969
@@ -13955,7 +13982,7 @@ namespace sqlite_orm {
1395513982 void release() {
1395613983 const maybe_lock maybeLock{_sync, !_openedForeverHint};
1395713984
13958- if (int prevCount = _retain_count .fetch_sub(
13985+ if (int prevCount = _retainCount .fetch_sub(
1395913986 1,
1396013987 maybeLock.isSynced
1396113988 // the lock above already synchronized everything, so we can just atomically decrement the counter
@@ -13984,36 +14011,41 @@ namespace sqlite_orm {
1398414011 * @attention While retrieving the reference count value is atomic it makes only sense at single-threaded points in code.
1398514012 */
1398614013 int retain_count() const {
13987- return _retain_count .load(std::memory_order_relaxed);
14014+ return _retainCount .load(std::memory_order_relaxed);
1398814015 }
1398914016
13990- const std::string filename;
13991-
1399214017 protected:
13993- sqlite3* db = nullptr;
14018+ alignas(polyfill::hardware_destructive_interference_size) sqlite3* db = nullptr;
1399414019
1399514020 private:
14021+ std::atomic_int _retainCount{};
1399614022 const bool _openedForeverHint = false;
13997- const std::function<void(sqlite3* db)> _onAfterOpen;
1399814023 std::binary_semaphore _sync{1};
13999- std::atomic_int _retain_count{};
14024+
14025+ private:
14026+ alignas(
14027+ polyfill::hardware_destructive_interference_size) const std::function<void(sqlite3* db)> _onAfterOpen;
14028+
14029+ public:
14030+ const std::string filename;
1400014031 };
1400114032#else
1400214033 struct connection_holder {
1400314034 connection_holder(std::string filename,
1400414035 bool /*openedForeverHint*/,
1400514036 std::function<void(sqlite3*)> onAfterOpen) :
14006- filename( std::move(filename)), _onAfterOpen{ std::move(onAfterOpen)} {}
14037+ _onAfterOpen{ std::move(onAfterOpen)}, filename( std::move(filename)) {}
1400714038
1400814039 connection_holder(const connection_holder&) = delete;
14040+
1400914041 connection_holder(const connection_holder& other, std::function<void(sqlite3*)> onAfterOpen) :
14010- filename{other.filename}, _onAfterOpen{std::move(onAfterOpen)} {}
14042+ _onAfterOpen{std::move(onAfterOpen)}, filename{other.filename } {}
1401114043
1401214044 void retain() {
1401314045 // first one opens the connection.
1401414046 // we presume that the connection is opened once in a single-threaded context [also open forever].
1401514047 // therefore we can just use an atomic increment but don't need sequencing due to `prevCount > 0`.
14016- if (_retain_count .fetch_add(1, std::memory_order_relaxed) == 0) {
14048+ if (_retainCount .fetch_add(1, std::memory_order_relaxed) == 0) {
1401714049 int rc = sqlite3_open(this->filename.c_str(), &this->db);
1401814050 if (rc != SQLITE_OK) SQLITE_ORM_CPP_UNLIKELY /*possible, but unexpected*/ {
1401914051 throw_translated_sqlite_error(this->db);
@@ -14028,7 +14060,7 @@ namespace sqlite_orm {
1402814060 void release() {
1402914061 // last one closes the connection.
1403014062 // we assume that this might happen by any thread, therefore the counter must serve as a synchronization point.
14031- if (_retain_count .fetch_sub(1, std::memory_order_acq_rel) == 1) {
14063+ if (_retainCount .fetch_sub(1, std::memory_order_acq_rel) == 1) {
1403214064 int rc = sqlite3_close(this->db);
1403314065 if (rc != SQLITE_OK) SQLITE_ORM_CPP_UNLIKELY {
1403414066 throw_translated_sqlite_error(this->db);
@@ -14047,17 +14079,26 @@ namespace sqlite_orm {
1404714079 * @attention While retrieving the reference count value is atomic it makes only sense at single-threaded points in code.
1404814080 */
1404914081 int retain_count() const {
14050- return _retain_count .load(std::memory_order_relaxed);
14082+ return _retainCount .load(std::memory_order_relaxed);
1405114083 }
1405214084
14053- const std::string filename;
14054-
1405514085 protected:
14056- sqlite3* db = nullptr;
14086+ #if SQLITE_ORM_ALIGNED_NEW_SUPPORTED
14087+ alignas(polyfill::hardware_destructive_interference_size)
14088+ #endif
14089+ sqlite3* db = nullptr;
14090+
14091+ private:
14092+ std::atomic_int _retainCount{};
1405714093
1405814094 private:
14059- const std::function<void(sqlite3* db)> _onAfterOpen;
14060- std::atomic_int _retain_count{};
14095+ #if SQLITE_ORM_ALIGNED_NEW_SUPPORTED
14096+ alignas(polyfill::hardware_destructive_interference_size)
14097+ #endif
14098+ const std::function<void(sqlite3* db)> _onAfterOpen;
14099+
14100+ public:
14101+ const std::string filename;
1406114102 };
1406214103#endif
1406314104
0 commit comments