-
First of, hi and thank you for this project. It makes working against SQLite databases a lot easier. It seems like I've managed to run into a multi-threaded issue. I am creating the storage as per below: namespace database_manager {
// A setting as represented in the database
struct SettingHolder {
int id = 0;
std::string name;
std::string value;
};
// A room as presented in the database
struct Room {
int id = 0;
std::string friendly_name;
int display_order = 0;
};
static inline auto get_db() {
auto db = sqlite_orm::make_storage("/data/nspanelmanager_db.sqlite3",
sqlite_orm::make_table("web_settings",
sqlite_orm::make_column("id", &SettingHolder::id, sqlite_orm::primary_key()),
sqlite_orm::make_column("name", &SettingHolder::name),
sqlite_orm::make_column("value", &SettingHolder::value)),
sqlite_orm::make_table("web_room",
sqlite_orm::make_column("id", &Room::id, sqlite_orm::primary_key()),
sqlite_orm::make_column("friendly_name", &Room::friendly_name),
sqlite_orm::make_column("displayOrder", &Room::display_order)));
return db;
}
}; // namespace database_manager When in the main thread I can simply do something like this: auto db_room = database_manager::get_db().get<database_manager::Room>(2);
SPDLOG_DEBUG("Got room {}::{}.", db_room.id, db_room.friendly_name);
auto db_setting = database_manager::get_db().get<database_manager::SettingHolder>(2);
SPDLOG_DEBUG("Got value {}", db_setting.value); and that works absolutely fine. However, If I then do the exact same thing in another thread it will simple crash as per the backtrace:
It seems that calling from a different thread causes sqlite3_mutex_enter to want to dereference a mutex that isn't set? I've looked though the issues on here that I found that talked about multi-threading and I've also tried reading up on how to do multi-threading with only SQLite3 but for the life of me I can't figure it out. I've tried both version 1.9 and version 1.8.2 from conan. Thankful for any help! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 28 replies
-
Hi. Thanks for such a warm feedback! This issue looks as usual multi-threading issue. Storage doesn't handle multi-threading for, it just passed the calls to SQLite engine. Of course there is a small responsibility area of storage itself which probably has to be covered with multi-threading primitives to handle cases like this but it will reduce performance in single-threaded apps. Quick advice: try to call |
Beta Was this translation helpful? Give feedback.
-
What you are reporting here seems really odd. Can you check the result of SQLite3 itself supports multiple concurrency modes, however it is threadsafe by default. There is a whole range of information available to give you a complete picture of multithreading and multiple access to a single database in SQLite: Especially because you are using a fresh sqlite_orm 'storage' instance on every call there should be no problem, as I understand it. Like @fnc12 I also suggest that you create the sqlite_orm 'storage' instance only once (i.e. a singleton), and use |
Beta Was this translation helpful? Give feedback.
-
It seems this may be the same issue as #1267 as it works just fine when compiled as STATIC instead of SHARED in CMake, big question is why. I can switch to using STATIC compilation but that would also mean that it takes a good while to recompile the binary every time I make changes so a better solution would be nice. |
Beta Was this translation helpful? Give feedback.
-
Well then, it seems the issue has been that when compiling with |
Beta Was this translation helpful? Give feedback.
Well then, it seems the issue has been that when compiling with
add_library(.... SHARED .....
in CMake it will import SQLite multiple times, changing this toadd_library(.... STATIC .....
will solve this issue. It would be nice if this is solvable in SQLite ORM but I'm not sure of how as I am surely no expert in CMake. Perhaps if SQLite ORM imported SQLite as PRIVATE? I'm not sure but it seems I've solved it for my use case anyways.