@@ -98,9 +98,12 @@ using std::nullptr_t;
98
98
#define SQLITE_ORM_STRUCTURED_BINDINGS_SUPPORTED
99
99
#endif
100
100
101
+ #if __cpp_aligned_new >= 201606L
102
+ #define SQLITE_ORM_ALIGNED_NEW_SUPPORTED
103
+ #endif
104
+
101
105
#if __cpp_generic_lambdas >= 201707L
102
106
#define SQLITE_ORM_EXPLICIT_GENERIC_LAMBDA_SUPPORTED
103
- #else
104
107
#endif
105
108
106
109
#if __cpp_init_captures >= 201803L
@@ -13887,6 +13890,30 @@ namespace sqlite_orm {
13887
13890
#include <string> // std::string
13888
13891
#endif
13889
13892
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
+
13890
13917
// #include "error_code.h"
13891
13918
13892
13919
namespace sqlite_orm {
@@ -13921,8 +13948,8 @@ namespace sqlite_orm {
13921
13948
};
13922
13949
13923
13950
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)) {}
13926
13953
13927
13954
connection_holder(const connection_holder&) = delete;
13928
13955
@@ -13936,7 +13963,7 @@ namespace sqlite_orm {
13936
13963
// `maybeLock.isSynced`: the lock above already synchronized everything, so we can just atomically increment the counter
13937
13964
// `!maybeLock.isSynced`: we presume that the connection is opened once in a single-threaded context [also open forever].
13938
13965
// 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) {
13940
13967
return;
13941
13968
}
13942
13969
@@ -13955,7 +13982,7 @@ namespace sqlite_orm {
13955
13982
void release() {
13956
13983
const maybe_lock maybeLock{_sync, !_openedForeverHint};
13957
13984
13958
- if (int prevCount = _retain_count .fetch_sub(
13985
+ if (int prevCount = _retainCount .fetch_sub(
13959
13986
1,
13960
13987
maybeLock.isSynced
13961
13988
// the lock above already synchronized everything, so we can just atomically decrement the counter
@@ -13984,36 +14011,41 @@ namespace sqlite_orm {
13984
14011
* @attention While retrieving the reference count value is atomic it makes only sense at single-threaded points in code.
13985
14012
*/
13986
14013
int retain_count() const {
13987
- return _retain_count .load(std::memory_order_relaxed);
14014
+ return _retainCount .load(std::memory_order_relaxed);
13988
14015
}
13989
14016
13990
- const std::string filename;
13991
-
13992
14017
protected:
13993
- sqlite3* db = nullptr;
14018
+ alignas(polyfill::hardware_destructive_interference_size) sqlite3* db = nullptr;
13994
14019
13995
14020
private:
14021
+ std::atomic_int _retainCount{};
13996
14022
const bool _openedForeverHint = false;
13997
- const std::function<void(sqlite3* db)> _onAfterOpen;
13998
14023
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;
14000
14031
};
14001
14032
#else
14002
14033
struct connection_holder {
14003
14034
connection_holder(std::string filename,
14004
14035
bool /*openedForeverHint*/,
14005
14036
std::function<void(sqlite3*)> onAfterOpen) :
14006
- filename( std::move(filename)), _onAfterOpen{ std::move(onAfterOpen)} {}
14037
+ _onAfterOpen{ std::move(onAfterOpen)}, filename( std::move(filename)) {}
14007
14038
14008
14039
connection_holder(const connection_holder&) = delete;
14040
+
14009
14041
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 } {}
14011
14043
14012
14044
void retain() {
14013
14045
// first one opens the connection.
14014
14046
// we presume that the connection is opened once in a single-threaded context [also open forever].
14015
14047
// 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) {
14017
14049
int rc = sqlite3_open(this->filename.c_str(), &this->db);
14018
14050
if (rc != SQLITE_OK) SQLITE_ORM_CPP_UNLIKELY /*possible, but unexpected*/ {
14019
14051
throw_translated_sqlite_error(this->db);
@@ -14028,7 +14060,7 @@ namespace sqlite_orm {
14028
14060
void release() {
14029
14061
// last one closes the connection.
14030
14062
// 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) {
14032
14064
int rc = sqlite3_close(this->db);
14033
14065
if (rc != SQLITE_OK) SQLITE_ORM_CPP_UNLIKELY {
14034
14066
throw_translated_sqlite_error(this->db);
@@ -14047,17 +14079,26 @@ namespace sqlite_orm {
14047
14079
* @attention While retrieving the reference count value is atomic it makes only sense at single-threaded points in code.
14048
14080
*/
14049
14081
int retain_count() const {
14050
- return _retain_count .load(std::memory_order_relaxed);
14082
+ return _retainCount .load(std::memory_order_relaxed);
14051
14083
}
14052
14084
14053
- const std::string filename;
14054
-
14055
14085
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{};
14057
14093
14058
14094
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;
14061
14102
};
14062
14103
#endif
14063
14104
0 commit comments