| 208 | } |
| 209 | |
| 210 | void SqliteLogger::writerLoop() |
| 211 | { |
| 212 | std::deque<Transition> transitions; |
| 213 | |
| 214 | // Signal readiness while holding the lock (establishes happens-before with constructor) |
| 215 | { |
| 216 | std::scoped_lock lk(queue_mutex_); |
| 217 | writer_ready_.store(true, std::memory_order_release); |
| 218 | } |
| 219 | queue_cv_.notify_one(); |
| 220 | |
| 221 | while(loop_) |
| 222 | { |
| 223 | transitions.clear(); |
| 224 | { |
| 225 | std::unique_lock lk(queue_mutex_); |
| 226 | queue_cv_.wait(lk, [this]() { return !transitions_queue_.empty() || !loop_; }); |
| 227 | std::swap(transitions, transitions_queue_); |
| 228 | } |
| 229 | |
| 230 | while(!transitions.empty()) |
| 231 | { |
| 232 | auto const trans = transitions.front(); |
| 233 | transitions.pop_front(); |
| 234 | |
| 235 | sqlite3_stmt* stmt = prepareStatement(db_, "INSERT INTO Transitions VALUES (?, ?, " |
| 236 | "?, ?, ?, ?)"); |
| 237 | sqlite3_bind_int64(stmt, 1, trans.timestamp); |
| 238 | sqlite3_bind_int(stmt, 2, session_id_); |
| 239 | sqlite3_bind_int(stmt, 3, trans.node_uid); |
| 240 | sqlite3_bind_int64(stmt, 4, trans.duration); |
| 241 | sqlite3_bind_int(stmt, 5, static_cast<int>(trans.status)); |
| 242 | sqlite3_bind_text(stmt, 6, trans.extra_data.c_str(), -1, SQLITE_TRANSIENT); |
| 243 | execStatement(stmt); |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | void BT::SqliteLogger::flush() |
| 249 | { |
nothing calls this directly
no test coverage detected