[Pkg-owncloud-commits] [owncloud-client] 118/211: Sql: Handle SQLITE_BUSY properly for sqlite3_step and sqlite3_prepare.

Sandro Knauß hefee-guest at moszumanska.debian.org
Sat Oct 25 09:10:35 UTC 2014


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit b5736fb5a7de6f95e5db35ad3012d2ec093fe5dc
Author: Klaas Freitag <freitag at owncloud.com>
Date:   Sat Oct 18 16:16:29 2014 +0200

    Sql: Handle SQLITE_BUSY properly for sqlite3_step and sqlite3_prepare.
    
    Repeat the statements a couple of times and sleep in between.
---
 csync/src/csync_statedb.c | 24 ++++++++++++++++++------
 src/mirall/ownsql.cpp     | 31 +++++++++++++++++++++++++++++--
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/csync/src/csync_statedb.c b/csync/src/csync_statedb.c
index 769573d..e5928e7 100644
--- a/csync/src/csync_statedb.c
+++ b/csync/src/csync_statedb.c
@@ -52,6 +52,19 @@
 
 #define sqlite_open(A, B) sqlite3_open_v2(A,B, SQLITE_OPEN_READONLY+SQLITE_OPEN_NOMUTEX, NULL)
 
+#define SQLTM_TIME 150000
+#define SQLTM_COUNT 10
+
+#define SQLITE_BUSY_HANDLED(F) if(1) { \
+    int n = 0; \
+    do { rc = F ; \
+      if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) { \
+         n++; \
+         usleep(SQLTM_TIME); \
+      } \
+    }while( (n < SQLTM_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED))); \
+  }
+
 
 void csync_set_statedb_exists(CSYNC *ctx, int val) {
   ctx->statedb.exists = val;
@@ -284,7 +297,7 @@ static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3
 
     column_count = sqlite3_column_count(stmt);
 
-    rc = sqlite3_step(stmt);
+    SQLITE_BUSY_HANDLED( sqlite3_step(stmt) );
 
     if( rc == SQLITE_ROW ) {
         if(column_count > 7) {
@@ -347,7 +360,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
   if( ctx->statedb.by_hash_stmt == NULL ) {
       const char *hash_query = "SELECT * FROM metadata WHERE phash=?1";
 
-      rc = sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL);
+      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL));
       if( rc != SQLITE_OK ) {
           CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query.");
           return NULL;
@@ -389,7 +402,6 @@ void   csync_statedb_finalize_statements(CSYNC *ctx) {
     }
 }
 
-
 csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
                                                       const char *file_id ) {
     csync_file_stat_t *st = NULL;
@@ -409,7 +421,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
     if( ctx->statedb.by_fileid_stmt == NULL ) {
         const char *query = "SELECT * FROM metadata WHERE fileid=?1";
 
-        rc = sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL);
+        SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL));
         if( rc != SQLITE_OK ) {
             CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query.");
             return NULL;
@@ -447,7 +459,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
   if( ctx->statedb.by_inode_stmt == NULL ) {
       const char *inode_query = "SELECT * FROM metadata WHERE inode=?1";
 
-      rc = sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL);
+      SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL));
       if( rc != SQLITE_OK ) {
           CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query.");
           return NULL;
@@ -509,7 +521,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) {
         return -1;
     }
 
-    rc = sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL);
+    SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL));
     if( rc != SQLITE_OK ) {
       CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query.");
       return -1;
diff --git a/src/mirall/ownsql.cpp b/src/mirall/ownsql.cpp
index 731597c..ac66c2c 100644
--- a/src/mirall/ownsql.cpp
+++ b/src/mirall/ownsql.cpp
@@ -17,6 +17,10 @@
 #include <QDebug>
 
 #include "ownsql.h"
+#include "utility.h"
+
+#define SQLITE_SLEEP_TIME_USEC 100000
+#define SQLITE_REPEAT_COUNT 20
 
 #define SQLITE_DO(A) if(1) { \
     _errId = (A); if(_errId != SQLITE_OK) { _error= QString::fromUtf8(sqlite3_errmsg(_db)); \
@@ -121,7 +125,17 @@ int SqlQuery::prepare( const QString& sql)
         finish();
     }
     if(!_sql.isEmpty() ) {
-        SQLITE_DO(sqlite3_prepare_v2(_db, _sql.toUtf8().constData(), -1, &_stmt, 0));
+        int n = 0;
+        int rc;
+        do {
+            rc = sqlite3_prepare_v2(_db, _sql.toUtf8().constData(), -1, &_stmt, 0);
+            if( (rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED) ) {
+                n++;
+                Mirall::Utility::usleep(SQLITE_SLEEP_TIME_USEC);
+            }
+        } while( (n < SQLITE_REPEAT_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED)));
+        _errId = rc;
+
         if( _errId != SQLITE_OK ) {
             qDebug() << "Sqlite prepare statement error:" << _error << "in"<<_sql;
         }
@@ -144,7 +158,20 @@ bool SqlQuery::exec()
 {
     // Don't do anything for selects, that is how we use the lib :-|
     if(_stmt && !isSelect() && !isPragma() ) {
-        SQLITE_DO(sqlite3_step(_stmt));
+        int rc, n = 0;
+        do {
+            rc = sqlite3_step(_stmt);
+            if( rc == SQLITE_LOCKED ) {
+                rc = sqlite3_reset(_stmt); /* This will also return SQLITE_LOCKED */
+                n++;
+                Mirall::Utility::usleep(SQLITE_SLEEP_TIME_USEC);
+            } else if( (rc == SQLITE_BUSY) ) {
+                Mirall::Utility::usleep(SQLITE_SLEEP_TIME_USEC);
+                n++;
+            }
+        } while( (n < SQLITE_REPEAT_COUNT) && ((rc == SQLITE_BUSY) || (rc == SQLITE_LOCKED)));
+        _errId = rc;
+
         return (_errId == SQLITE_DONE); // either SQLITE_ROW or SQLITE_DONE
     }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list