// returns 0 for OK, -1 for exception int ManagedDatasource::closeUnlocked(ExceptionSink *xsink) { int rc = 0; if (grabLock(xsink)) return -1; if (isOpen()) { if (isInTransaction()) { if (!wasConnectionAborted()) { // FIXME: check for statement xsink->raiseException("DATASOURCE-TRANSACTION-EXCEPTION", "%s:%s@%s: Datasource closed while in a transaction; transaction will be automatically rolled back and the lock released", getDriverName(), getUsernameStr().c_str(), getDBNameStr().c_str()); Datasource::rollback(xsink); } remove_thread_resource(this); setTransactionStatus(false); // force-exit the transaction lock forceReleaseLockIntern(); rc = -1; } Datasource::close(); } return rc; }
void SessionInitialiser::execute() { Scope x( log() ); SessionInitialiserData::State state = d->state; do { state = d->state; switch ( d->state ) { case SessionInitialiserData::NoTransaction: findSessions(); if ( d->sessions.isEmpty() ) { emitUpdates(); d->state = SessionInitialiserData::QueriesDone; } else { grabLock(); d->state = SessionInitialiserData::WaitingForLock; } break; case SessionInitialiserData::SessionInitialiserData::WaitingForLock: findRecent(); if ( !d->recent || d->recent->done() ) d->state = SessionInitialiserData::HaveUidnext; break; case SessionInitialiserData::HaveUidnext: findMailboxChanges(); d->state = SessionInitialiserData::ReceivingChanges; break; case SessionInitialiserData::ReceivingChanges: recordMailboxChanges(); recordExpunges(); if ( d->messages->done() && ( !d->expunges || d->expunges->done() ) ) d->state = SessionInitialiserData::Updated; break; case SessionInitialiserData::Updated: releaseLock(); // may change d->state break; case SessionInitialiserData::QueriesDone: break; } } while ( state != d->state ); if ( d->t && d->t->failed() ) { releaseLock(); d->t = 0; } // when we come down here, we either have a callback from a query // or we don't. if we don't, we're done and Allocator will deal // with the object. }
int ManagedDatasource::startDBAction(ExceptionSink *xsink, bool &new_transaction) { AutoLocker al(&ds_lock); // save previous trans lock status new_transaction = (tid != gettid()); // first grab the transaction lock if (grabLock(xsink)) return -1; // open the datasource if necessary if (!isOpen() && (Datasource::open(xsink) || *xsink)) { // release transaction lock if necessary if (new_transaction) releaseLockIntern(); return -1; } //printd(0, "ManagedDatasource::startDBAction() this=%p need_lock=%d new_trans=%p had_lock=%d\n", this, need_transaction_lock, new_transaction, had_lock); return 0; }