From 9811f22cabcc8708113e833ddde6748d9435f66a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 7 Jul 2011 07:59:09 +0200 Subject: [PATCH] QueryParser: Explicitly suspend/resume iterators Extended policy by IndexIteratorSuspend() and IndexIteratorResume() methods that are invoked for the index iterator by Query::GetNextEntry() after entering respectively before exiting. --- headers/private/file_systems/QueryParser.h | 77 +++++++++++-------- .../kernel/file_systems/packagefs/Query.cpp | 10 +++ 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/headers/private/file_systems/QueryParser.h b/headers/private/file_systems/QueryParser.h index 05d82ca7e2..774d7857a8 100644 --- a/headers/private/file_systems/QueryParser.h +++ b/headers/private/file_systems/QueryParser.h @@ -150,7 +150,7 @@ public: Query*& _query); status_t Rewind(); - status_t GetNextEntry(struct dirent* , size_t size); + inline status_t GetNextEntry(struct dirent* dirent, size_t size); void LiveUpdate(Entry* entry, Node* node, const char* attribute, int32 type, @@ -168,6 +168,7 @@ public: { return fFlags; } private: + status_t _GetNextEntry(struct dirent* dirent, size_t size); void _SendEntryNotification(Entry* entry, status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t)); @@ -1755,38 +1756,15 @@ template status_t Query::GetNextEntry(struct dirent* dirent, size_t size) { - // If we don't have an equation to use yet/anymore, get a new one - // from the stack - while (true) { - if (fIterator == NULL) { - if (!fStack.Pop(&fCurrent) - || fCurrent == NULL) - return B_ENTRY_NOT_FOUND; + if (fIterator != NULL) + QueryPolicy::IndexIteratorResume(fIterator); - status_t status = fCurrent->PrepareQuery(fContext, fIndex, - &fIterator, fFlags & B_QUERY_NON_INDEXED); - if (status == B_ENTRY_NOT_FOUND) { - // try next equation - continue; - } + status_t error = _GetNextEntry(dirent, size); - if (status != B_OK) - return status; - } - if (fCurrent == NULL) - QUERY_RETURN_ERROR(B_ERROR); + if (fIterator != NULL) + QueryPolicy::IndexIteratorSuspend(fIterator); - status_t status = fCurrent->GetNextMatching(fContext, fIterator, dirent, - size); - if (status != B_OK) { - QueryPolicy::IndexIteratorDelete(fIterator); - fIterator = NULL; - fCurrent = NULL; - } else { - // only return if we have another entry - return B_OK; - } - } + return error; } @@ -1897,6 +1875,45 @@ Query::LiveUpdateRenameMove(Entry* entry, Node* node, } +template +status_t +Query::_GetNextEntry(struct dirent* dirent, size_t size) +{ + // If we don't have an equation to use yet/anymore, get a new one + // from the stack + while (true) { + if (fIterator == NULL) { + if (!fStack.Pop(&fCurrent) + || fCurrent == NULL) + return B_ENTRY_NOT_FOUND; + + status_t status = fCurrent->PrepareQuery(fContext, fIndex, + &fIterator, fFlags & B_QUERY_NON_INDEXED); + if (status == B_ENTRY_NOT_FOUND) { + // try next equation + continue; + } + + if (status != B_OK) + return status; + } + if (fCurrent == NULL) + QUERY_RETURN_ERROR(B_ERROR); + + status_t status = fCurrent->GetNextMatching(fContext, fIterator, dirent, + size); + if (status != B_OK) { + QueryPolicy::IndexIteratorDelete(fIterator); + fIterator = NULL; + fCurrent = NULL; + } else { + // only return if we have another entry + return B_OK; + } + } +} + + template void Query::_SendEntryNotification(Entry* entry, diff --git a/src/add-ons/kernel/file_systems/packagefs/Query.cpp b/src/add-ons/kernel/file_systems/packagefs/Query.cpp index 0c9078944e..05424e1087 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Query.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Query.cpp @@ -154,6 +154,16 @@ struct Query::QueryPolicy { return B_OK; } + static void IndexIteratorSuspend(IndexIterator* indexIterator) + { + indexIterator->Suspend(); + } + + static void IndexIteratorResume(IndexIterator* indexIterator) + { + indexIterator->Resume(); + } + // Node interface static const off_t NodeGetSize(Node* node)