Akonadi

sqlite_blocking.cpp
1 /*
2  Copyright (c) 2009 Bertjan Broeksema <[email protected]>
3  Copyright (c) 2014 Daniel Vrátil <[email protected]>
4 
5  This library is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or (at your
8  option) any later version.
9 
10  This library is distributed in the hope that it will be useful, but WITHOUT
11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13  License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301, USA.
19 */
20 
21 #include "sqlite_blocking.h"
22 
23 #include <sqlite3.h>
24 
25 #include <QMutex>
26 #include <QWaitCondition>
27 #include "qdebug.h"
28 #include <QStringBuilder>
29 #include <QThread>
30 
31 QString debugString()
32 {
33  return QString(QLatin1String("[QSQLITE3: ") + QString::number(quint64(QThread::currentThreadId())) + QLatin1String("] "));
34 }
35 
36 /* Based on example in http://www.sqlite.org/unlock_notify.html */
37 
38 struct UnlockNotification {
39  bool fired;
40  QWaitCondition cond;
41  QMutex mutex;
42 };
43 
44 static void qSqlite3UnlockNotifyCb(void **apArg, int nArg)
45 {
46  for (int i = 0; i < nArg; ++i) {
47  UnlockNotification *ntf = static_cast<UnlockNotification *>(apArg[i]);
48  ntf->mutex.lock();
49  ntf->fired = true;
50  ntf->cond.wakeOne();
51  ntf->mutex.unlock();
52  }
53 }
54 
55 static int qSqlite3WaitForUnlockNotify(sqlite3 *db)
56 {
57  int rc;
58  UnlockNotification un;
59  un.fired = false;
60 
61  rc = sqlite3_unlock_notify(db, qSqlite3UnlockNotifyCb, (void *)&un);
62  Q_ASSERT(rc == SQLITE_LOCKED || rc == SQLITE_OK);
63 
64  if (rc == SQLITE_OK) {
65  un.mutex.lock();
66  if (!un.fired) {
67  un.cond.wait(&un.mutex);
68  }
69  un.mutex.unlock();
70  }
71 
72  return rc;
73 }
74 
75 int sqlite3_blocking_step(sqlite3_stmt *pStmt)
76 {
77  int rc;
78  while (SQLITE_LOCKED_SHAREDCACHE == (rc = sqlite3_step(pStmt))) {
79  //qDebug() << debugString() << "sqlite3_blocking_step: Waiting..."; QTime now; now.start();
80  rc = qSqlite3WaitForUnlockNotify(sqlite3_db_handle(pStmt));
81  //qDebug() << debugString() << "sqlite3_blocking_step: Waited for " << now.elapsed() << "ms";
82  if (rc != SQLITE_OK) {
83  break;
84  }
85  sqlite3_reset(pStmt);
86  }
87 
88  return rc;
89 }
90 
91 int sqlite3_blocking_prepare16_v2(sqlite3 *db, const void *zSql, int nSql,
92  sqlite3_stmt **ppStmt, const void **pzTail)
93 {
94  int rc;
95  while (SQLITE_LOCKED_SHAREDCACHE == (rc = sqlite3_prepare16_v2(db, zSql, nSql, ppStmt, pzTail))) {
96  //qDebug() << debugString() << "sqlite3_blocking_prepare16_v2: Waiting..."; QTime now; now.start();
97  rc = qSqlite3WaitForUnlockNotify(db);
98  //qDebug() << debugString() << "sqlite3_blocking_prepare16_v2: Waited for " << now.elapsed() << "ms";
99  if (rc != SQLITE_OK) {
100  break;
101  }
102  }
103 
104  return rc;
105 }
QString number(int n, int base)
Qt::HANDLE currentThreadId()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed May 27 2020 22:43:40 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.