* Added flags for removing/unremoving the node.

* Added more optional notification parameters to Commit().
* Added some handy methods.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-07-20 16:59:53 +00:00
parent f286792113
commit 72e9c2846a
2 changed files with 83 additions and 13 deletions

View File

@ -71,7 +71,9 @@ Transaction::StartAndAddNode(Node* node, uint32 flags = 0)
status_t
Transaction::Commit(const PostCommitNotification* notification)
Transaction::Commit(const PostCommitNotification* notification1,
const PostCommitNotification* notification2,
const PostCommitNotification* notification3)
{
ASSERT(fID >= 0);
@ -94,8 +96,12 @@ Transaction::Commit(const PostCommitNotification* notification)
}
// send notifications
if (notification != NULL)
notification->NotifyPostCommit();
if (notification1 != NULL)
notification1->NotifyPostCommit();
if (notification2 != NULL)
notification2->NotifyPostCommit();
if (notification3 != NULL)
notification3->NotifyPostCommit();
// clean up
_DeleteNodeInfosAndUnlock(false);
@ -135,6 +141,8 @@ Transaction::Abort()
status_t
Transaction::AddNode(Node* node, uint32 flags)
{
ASSERT(fID >= 0);
NodeInfo* info = _GetNodeInfo(node);
if (info != NULL)
return B_OK;
@ -159,6 +167,8 @@ Transaction::AddNode(Node* node, uint32 flags)
status_t
Transaction::AddNodes(Node* node1, Node* node2, Node* node3)
{
ASSERT(fID >= 0);
// sort the nodes
swap_if_greater(node1, node2);
if (node3 != NULL && swap_if_greater(node2, node3))
@ -175,9 +185,41 @@ Transaction::AddNodes(Node* node1, Node* node2, Node* node3)
}
bool
Transaction::RemoveNode(Node* node)
{
ASSERT(fID >= 0);
NodeInfo* info = _GetNodeInfo(node);
if (info == NULL)
return false;
fNodeInfos.Remove(info);
_DeleteNodeInfoAndUnlock(info, false);
return true;
}
void
Transaction::UpdateNodeFlags(Node* node, uint32 flags)
{
ASSERT(fID >= 0);
NodeInfo* info = _GetNodeInfo(node);
if (info == NULL)
return;
info->flags = flags;
}
void
Transaction::KeepNode(Node* node)
{
ASSERT(fID >= 0);
NodeInfo* info = _GetNodeInfo(node);
if (info == NULL)
return;
@ -202,13 +244,26 @@ Transaction::_GetNodeInfo(Node* node) const
void
Transaction::_DeleteNodeInfosAndUnlock(bool failed)
{
while (NodeInfo* info = fNodeInfos.RemoveHead()) {
if ((info->flags & TRANSACTION_DELETE_NODE) != 0)
delete info->node;
else if ((info->flags & TRANSACTION_KEEP_NODE_LOCKED) == 0)
info->node->WriteUnlock();
delete info;
while (NodeInfo* info = fNodeInfos.RemoveHead())
_DeleteNodeInfoAndUnlock(info, failed);
}
void
Transaction::_DeleteNodeInfoAndUnlock(NodeInfo* info, bool failed)
{
if (failed) {
if ((info->flags & TRANSACTION_REMOVE_NODE_ON_ERROR) != 0)
fVolume->RemoveNode(info->node);
else if ((info->flags & TRANSACTION_UNREMOVE_NODE_ON_ERROR) != 0)
fVolume->UnremoveNode(info->node);
}
if ((info->flags & TRANSACTION_DELETE_NODE) != 0)
delete info->node;
else if ((info->flags & TRANSACTION_KEEP_NODE_LOCKED) == 0)
info->node->WriteUnlock();
delete info;
}

View File

@ -18,9 +18,11 @@ class Volume;
enum {
TRANSACTION_DELETE_NODE = 0x1,
TRANSACTION_NODE_ALREADY_LOCKED = 0x2,
TRANSACTION_KEEP_NODE_LOCKED = 0x4
TRANSACTION_DELETE_NODE = 0x01,
TRANSACTION_NODE_ALREADY_LOCKED = 0x02,
TRANSACTION_KEEP_NODE_LOCKED = 0x04,
TRANSACTION_REMOVE_NODE_ON_ERROR = 0x08,
TRANSACTION_UNREMOVE_NODE_ON_ERROR = 0x10
};
@ -34,18 +36,29 @@ public:
status_t Start();
status_t StartAndAddNode(Node* node, uint32 flags = 0);
status_t Commit(
const PostCommitNotification* notification
const PostCommitNotification* notification1
= NULL,
const PostCommitNotification* notification2
= NULL,
const PostCommitNotification* notification3
= NULL);
inline status_t Commit(
const PostCommitNotification& notification);
void Abort();
inline bool IsActive() const { return fID >= 0; }
status_t AddNode(Node* node, uint32 flags = 0);
status_t AddNodes(Node* node1, Node* node2,
Node* node3 = NULL);
bool RemoveNode(Node* node);
void UpdateNodeFlags(Node* node, uint32 flags);
void KeepNode(Node* node);
bool IsNodeLocked(Node* node) const
{ return _GetNodeInfo(node) != NULL; }
private:
struct NodeInfo : DoublyLinkedListLinkImpl<NodeInfo> {
Node* node;
@ -58,6 +71,8 @@ private:
private:
NodeInfo* _GetNodeInfo(Node* node) const;
void _DeleteNodeInfosAndUnlock(bool failed);
void _DeleteNodeInfoAndUnlock(NodeInfo* info,
bool failed);
private:
Volume* fVolume;