@@ -10,24 +10,17 @@ SQLiteOPResult genericSqliteOpenDb(string const dbName, string const docPath,
1010ConnectionState::ConnectionState (const std::string dbName,
1111 const std::string docPath, int SQLFlags) {
1212 auto result = genericSqliteOpenDb (dbName, docPath, &connection, SQLFlags);
13- isClosed = false ;
14-
15- this -> clearLock ();
16- threadDone = false ;
17- thread = new std::thread (&ConnectionState::doWork, this );
13+ if (result. type != SQLiteOk) {
14+ throw std::runtime_error ( " Failed to open SQLite database: " + result. errorMessage );
15+ }
16+ thread = std::thread (&ConnectionState::doWork, this ) ;
17+ this -> clearLock ( );
1818}
1919
2020ConnectionState::~ConnectionState () {
21- // So threads know it's time to shut down
22- threadDone = true ;
23-
24- // Wake up all the threads, so they can finish and be joined
25- workQueueConditionVariable.notify_all ();
26- if (thread->joinable ()) {
27- thread->join ();
21+ if (!isClosed) {
22+ close ();
2823 }
29-
30- delete thread;
3124}
3225
3326void ConnectionState::clearLock () {
@@ -65,10 +58,25 @@ std::future<void> ConnectionState::refreshSchema() {
6558}
6659
6760void ConnectionState::close () {
61+ // prevent any new work from being queued
6862 isClosed = true ;
63+
64+ // Wait for the work queue to empty
6965 waitFinished ();
70- // So that the thread can stop (if not already)
71- threadDone = true ;
66+
67+ {
68+ // Now signal the thread to stop and notify it
69+ std::lock_guard<std::mutex> g (workQueueMutex);
70+ threadDone = true ;
71+ workQueueConditionVariable.notify_all ();
72+ }
73+
74+ // Join the worker thread
75+ if (thread.joinable ()) {
76+ thread.join ();
77+ }
78+
79+ // Safely close the SQLite connection
7280 sqlite3_close_v2 (connection);
7381}
7482
@@ -77,14 +85,12 @@ void ConnectionState::queueWork(std::function<void(sqlite3 *)> task) {
7785 throw std::runtime_error (" Connection is not open. Connection has been closed before queueing work." );
7886 }
7987
80- // Grab the mutex
81- std::lock_guard<std::mutex> g (workQueueMutex);
82-
83- // Push the request to the queue
84- workQueue.push (task);
88+ {
89+ std::lock_guard<std::mutex> g (workQueueMutex);
90+ workQueue.push (task);
91+ }
8592
86- // Notify one thread that there are requests to process
87- workQueueConditionVariable.notify_all ();
93+ workQueueConditionVariable.notify_all ();
8894}
8995
9096void ConnectionState::doWork () {
@@ -124,11 +130,8 @@ void ConnectionState::doWork() {
124130
125131void ConnectionState::waitFinished () {
126132 std::unique_lock<std::mutex> g (workQueueMutex);
127- if (workQueue.empty ()) {
128- return ;
129- }
130133 workQueueConditionVariable.wait (
131- g, [&] { return workQueue.empty () && ( threadBusy == false ) ; });
134+ g, [&] { return workQueue.empty () && ! threadBusy; });
132135}
133136
134137SQLiteOPResult genericSqliteOpenDb (string const dbName, string const docPath,
0 commit comments