Akonadi

sqlite_blocking.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Bertjan Broeksema <[email protected]>
3  SPDX-FileCopyrightText: 2014 Daniel Vr├ítil <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "sqlite_blocking.h"
9 
10 #include <sqlite3.h>
11 
12 #include "qdebug.h"
13 #include <QMutex>
14 #include <QStringBuilder>
15 #include <QThread>
16 #include <QWaitCondition>
17 
18 QString debugString()
19 {
20  return QString(QLatin1String("[QSQLITE3: ") + QString::number(quint64(QThread::currentThreadId())) + QLatin1String("] "));
21 }
22 
23 /* Based on example in http://www.sqlite.org/unlock_notify.html */
24 
25 struct UnlockNotification {
26  bool fired;
27  QWaitCondition cond;
28  QMutex mutex;
29 };
30 
31 static void qSqlite3UnlockNotifyCb(void **apArg, int nArg)
32 {
33  for (int i = 0; i < nArg; ++i) {
34  auto ntf = static_cast<UnlockNotification *>(apArg[i]);
35  ntf->mutex.lock();
36  ntf->fired = true;
37  ntf->cond.wakeOne();
38  ntf->mutex.unlock();
39  }
40 }
41 
42 static int qSqlite3WaitForUnlockNotify(sqlite3 *db)
43 {
44  int rc;
45  UnlockNotification un;
46  un.fired = false;
47 
48  rc = sqlite3_unlock_notify(db, qSqlite3UnlockNotifyCb, (void *)&un);
49  Q_ASSERT(rc == SQLITE_LOCKED || rc == SQLITE_OK);
50 
51  if (rc == SQLITE_OK) {
52  un.mutex.lock();
53  if (!un.fired) {
54  un.cond.wait(&un.mutex);
55  }
56  un.mutex.unlock();
57  }
58 
59  return rc;
60 }
61 
62 int sqlite3_blocking_step(sqlite3_stmt *pStmt)
63 {
64  int rc;
65  while (SQLITE_LOCKED_SHAREDCACHE == (rc = sqlite3_step(pStmt))) {
66  // qDebug() << debugString() << "sqlite3_blocking_step: Waiting..."; QTime now; now.start();
67  rc = qSqlite3WaitForUnlockNotify(sqlite3_db_handle(pStmt));
68  // qDebug() << debugString() << "sqlite3_blocking_step: Waited for " << now.elapsed() << "ms";
69  if (rc != SQLITE_OK) {
70  break;
71  }
72  sqlite3_reset(pStmt);
73  }
74 
75  return rc;
76 }
77 
78 int sqlite3_blocking_prepare16_v2(sqlite3 *db, const void *zSql, int nSql, sqlite3_stmt **ppStmt, const void **pzTail)
79 {
80  int rc;
81  while (SQLITE_LOCKED_SHAREDCACHE == (rc = sqlite3_prepare16_v2(db, zSql, nSql, ppStmt, pzTail))) {
82  // qDebug() << debugString() << "sqlite3_blocking_prepare16_v2: Waiting..."; QTime now; now.start();
83  rc = qSqlite3WaitForUnlockNotify(db);
84  // qDebug() << debugString() << "sqlite3_blocking_prepare16_v2: Waited for " << now.elapsed() << "ms";
85  if (rc != SQLITE_OK) {
86  break;
87  }
88  }
89 
90  return rc;
91 }
QString number(int n, int base)
Qt::HANDLE currentThreadId()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jul 2 2022 06:41:49 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.