diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-16 14:03:48 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-16 16:03:57 +0200 |
commit | 12c3579136b6925e75cca4f3a9b8bae2e4665db7 (patch) | |
tree | 17f82a28141856af0954ffe4eff20ebc679a3265 /src/imports | |
parent | c1c526aafb2fc70ac6155eb775b3784f1e2e6504 (diff) |
Speed up exception propagation
Avoid catch (...) with re-throw as it turns that this is very slow because it
throws a new exception and the unwinder starts from scratch. Instead use stack
allocated objects and cleaning destructors to restore state before continuing
with the propagation of exceptions.
Change-Id: I6d95026bcd60b58cb6258a9dae28623a46739532
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/imports')
-rw-r--r-- | src/imports/localstorage/plugin.cpp | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 84bcb756e8..9a0528a28f 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -322,6 +322,35 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx) return result.asReturnedValue(); } +struct TransactionRollback { + QSqlDatabase *db; + bool *inTransactionFlag; + + TransactionRollback(QSqlDatabase *database, bool *transactionFlag) + : db(database) + , inTransactionFlag(transactionFlag) + { + if (inTransactionFlag) + *inTransactionFlag = true; + } + + ~TransactionRollback() + { + if (inTransactionFlag) + *inTransactionFlag = false; + if (db) + db->rollback(); + } + + void clear() { + db = 0; + if (inTransactionFlag) + *inTransactionFlag = false; + inTransactionFlag = 0; + } +}; + + static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx) { if (ctx->callData->argc < 2) @@ -349,7 +378,6 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx) w->type = QQmlSqlDatabaseWrapper::Query; w->database = db; w->version = r->version; - w->inTransaction = true; bool ok = true; if (!!callback) { @@ -359,12 +387,10 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx) ScopedCallData callData(scope, 1); callData->thisObject = engine->global(); callData->args[0] = w; - try { - callback->call(callData); - } catch (...) { - db.rollback(); - ctx->rethrowException(); - } + + TransactionRollback rollbackOnException(&db, &w->inTransaction); + callback->call(callData); + rollbackOnException.clear(); if (!db.commit()) { db.rollback(); V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR,QQmlEngine::tr("SQL transaction failed")); @@ -373,8 +399,6 @@ static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx) } } - w->inTransaction = false; - if (ok) { w->version = to_version; #ifndef QT_NO_SETTINGS @@ -408,22 +432,15 @@ static ReturnedValue qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, b w->database = db; w->version = r->version; w->readonly = readOnly; - w->inTransaction = true; db.transaction(); if (callback) { ScopedCallData callData(scope, 1); callData->thisObject = engine->global(); callData->args[0] = w; - try { - callback->call(callData); - } catch (...) { - w->inTransaction = false; - db.rollback(); - ctx->rethrowException(); - } - - w->inTransaction = false; + TransactionRollback rollbackOnException(&db, &w->inTransaction); + callback->call(callData); + rollbackOnException.clear(); if (!db.commit()) db.rollback(); |