summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/hbtree/hbtree.cpp17
-rw-r--r--src/hbtree/hbtree_p.h1
-rw-r--r--tests/auto/hbtree/main.cpp12
3 files changed, 26 insertions, 4 deletions
diff --git a/src/hbtree/hbtree.cpp b/src/hbtree/hbtree.cpp
index 5e8f0810..46b3585c 100644
--- a/src/hbtree/hbtree.cpp
+++ b/src/hbtree/hbtree.cpp
@@ -91,7 +91,7 @@ const quint32 HBtreePrivate::PageInfo::INVALID_PAGE = 0xFFFFFFFF;
HBtreePrivate::HBtreePrivate(HBtree *q, const QString &name)
: q_ptr(q), fileName_(name), fd_(-1), openMode_(HBtree::ReadOnly), size_(0), lastSyncedId_(0), cacheSize_(20),
compareFunction_(0),
- writeTransaction_(0), lastPage_(PageInfo::INVALID_PAGE), cursorDisrupted_(false)
+ writeTransaction_(0), readTransaction_(0), lastPage_(PageInfo::INVALID_PAGE), cursorDisrupted_(false)
{
}
@@ -209,6 +209,8 @@ bool HBtreePrivate::open(int fd)
void HBtreePrivate::close(bool doSync)
{
+ HBTREE_ASSERT(!readTransaction_ && !writeTransaction_);
+
if (fd_ != -1) {
HBTREE_DEBUG("closing btree with fd:" << fd_);
if (doSync)
@@ -931,9 +933,13 @@ void HBtreePrivate::abort(HBtreeTransaction *transaction)
}
dirtyPages_.clear();
if (transaction->isReadWrite()) {
+ HBTREE_ASSERT(transaction == writeTransaction_);
if (::flock(fd_, LOCK_UN) != 0)
HBTREE_ERROR("failed to unlock file with transaction @" << transaction);
writeTransaction_ = 0;
+ } else {
+ HBTREE_ASSERT(transaction == readTransaction_);
+ readTransaction_ = 0;
}
delete transaction;
cachePrune();
@@ -998,6 +1004,13 @@ HBtreeTransaction *HBtreePrivate::beginTransaction(HBtreeTransaction::Type type)
{
Q_Q(HBtree);
+ HBTREE_ASSERT(!writeTransaction_ && !readTransaction_);
+
+ if (writeTransaction_ || readTransaction_) {
+ HBTREE_ERROR("Only one transaction type supported at a time");
+ return 0;
+ }
+
if (type == HBtreeTransaction::ReadWrite && writeTransaction_) {
HBTREE_ERROR("cannot open write transaction when one in progress");
return 0;
@@ -1031,6 +1044,8 @@ HBtreeTransaction *HBtreePrivate::beginTransaction(HBtreeTransaction::Type type)
transaction->revision_ = marker_.meta.revision;
if (type == HBtreeTransaction::ReadWrite)
writeTransaction_ = transaction;
+ else
+ readTransaction_ = transaction;
HBTREE_DEBUG("began" << (transaction->isReadOnly() ? "read" : "write")
<< "transaction @" << transaction
<< "[root:" << transaction->rootPage_
diff --git a/src/hbtree/hbtree_p.h b/src/hbtree/hbtree_p.h
index ab529797..8575db31 100644
--- a/src/hbtree/hbtree_p.h
+++ b/src/hbtree/hbtree_p.h
@@ -388,6 +388,7 @@ public:
PageMap dirtyPages_;
HBtree::CompareFunction compareFunction_;
HBtreeTransaction *writeTransaction_;
+ HBtreeTransaction *readTransaction_;
QSet<quint32> collectiblePages_;
PageMap cache_;
quint32 lastPage_;
diff --git a/tests/auto/hbtree/main.cpp b/tests/auto/hbtree/main.cpp
index 517feb04..41cf02c8 100644
--- a/tests/auto/hbtree/main.cpp
+++ b/tests/auto/hbtree/main.cpp
@@ -2107,6 +2107,7 @@ void TestHBtree::deleteReinsertVerify()
keyValueMap.insert(it.key(), it.value());
++it;
}
+ txn->commit(0);
// Verify in order.
txn = db->beginTransaction(HBtreeTransaction::ReadOnly);
@@ -2226,16 +2227,21 @@ void TestHBtree::tag()
QVERIFY(txn);
QVERIFY(txn->put(QByteArray("foo"), QByteArray("123")));
QCOMPARE(db->tag(), 42u);
- // do not commit just yet
+
+ // This test held off on a commit until the read was done. But for now we don't allow
+ // simultaneous reads and writes.
+ txn->abort();
HBtreeTransaction *rtxn = db->beginTransaction(HBtreeTransaction::ReadOnly);
QVERIFY(rtxn);
QCOMPARE(rtxn->tag(), 42u);
+ rtxn->abort();
+ txn = db->beginTransaction(HBtreeTransaction::ReadWrite);
+ QVERIFY(txn);
QVERIFY(txn->commit(64u));
QCOMPARE(db->tag(), 64u);
- QCOMPARE(rtxn->tag(), 42u);
- rtxn->abort();
+
rtxn = db->beginTransaction(HBtreeTransaction::ReadOnly);
QVERIFY(rtxn);
QCOMPARE(rtxn->tag(), 64u);