Equation::Match() unlocked the small data section too soon (the contents
could be changed before or during the comparison). Some style changes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1861 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -788,6 +788,7 @@ Equation::Match(Inode *inode,const char *attributeName,int32 type,const uint8 *k
|
||||
// get a pointer to the attribute in question
|
||||
union value value;
|
||||
uint8 *buffer;
|
||||
bool locked = false;
|
||||
|
||||
// first, check if we are matching for a live query and use that value
|
||||
if (attributeName != NULL && !strcmp(fAttribute, attributeName)) {
|
||||
@@ -823,7 +824,7 @@ Equation::Match(Inode *inode,const char *attributeName,int32 type,const uint8 *k
|
||||
buffer = smallData->Data();
|
||||
type = smallData->type;
|
||||
size = smallData->data_size;
|
||||
inode->SmallDataLock().Unlock();
|
||||
locked = true;
|
||||
} else {
|
||||
// needed to unlock the small_data section as fast as possible
|
||||
inode->SmallDataLock().Unlock();
|
||||
@@ -850,6 +851,9 @@ Equation::Match(Inode *inode,const char *attributeName,int32 type,const uint8 *k
|
||||
if (status == B_OK)
|
||||
status = CompareTo(buffer, size) ? MATCH_OK : NO_MATCH;
|
||||
|
||||
if (locked)
|
||||
inode->SmallDataLock().Unlock();
|
||||
|
||||
RETURN_ERROR(status);
|
||||
}
|
||||
|
||||
@@ -957,7 +961,8 @@ Equation::PrepareQuery(Volume */*volume*/, Index &index, TreeIterator **iterator
|
||||
status = (*iterator)->Find(Value(),keySize);
|
||||
if (fOp == OP_EQUAL && !fIsPattern)
|
||||
return status;
|
||||
else if (status == B_ENTRY_NOT_FOUND && (fIsPattern || fOp == OP_GREATER_THAN || fOp == OP_GREATER_THAN_OR_EQUAL))
|
||||
else if (status == B_ENTRY_NOT_FOUND
|
||||
&& (fIsPattern || fOp == OP_GREATER_THAN || fOp == OP_GREATER_THAN_OR_EQUAL))
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -978,7 +983,8 @@ Equation::GetNextMatching(Volume *volume, TreeIterator *iterator,
|
||||
uint16 duplicate;
|
||||
off_t offset;
|
||||
|
||||
status_t status = iterator->GetNextEntry(&indexValue,&keyLength,(uint16)sizeof(indexValue),&offset,&duplicate);
|
||||
status_t status = iterator->GetNextEntry(&indexValue, &keyLength,
|
||||
(uint16)sizeof(indexValue), &offset, &duplicate);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@@ -1487,7 +1493,8 @@ Query::SetLiveMode(port_id port,int32 token)
|
||||
|
||||
|
||||
void
|
||||
Query::LiveUpdate(Inode *inode,const char *attribute,int32 type,const uint8 *oldKey,size_t oldLength,const uint8 *newKey,size_t newLength)
|
||||
Query::LiveUpdate(Inode *inode, const char *attribute, int32 type, const uint8 *oldKey,
|
||||
size_t oldLength, const uint8 *newKey, size_t newLength)
|
||||
{
|
||||
if (fPort < 0 || fExpression == NULL || attribute == NULL)
|
||||
return;
|
||||
@@ -1502,7 +1509,8 @@ Query::LiveUpdate(Inode *inode,const char *attribute,int32 type,const uint8 *old
|
||||
if (oldKey == NULL || strcmp(attribute,"name"))
|
||||
return;
|
||||
|
||||
send_notification(fPort,fToken,B_QUERY_UPDATE,B_ENTRY_REMOVED,fVolume->ID(),0,fVolume->ToVnode(inode->Parent()),0,inode->ID(),(const char *)oldKey);
|
||||
send_notification(fPort, fToken, B_QUERY_UPDATE, B_ENTRY_REMOVED, fVolume->ID(), 0,
|
||||
fVolume->ToVnode(inode->Parent()), 0, inode->ID(), (const char *)oldKey);
|
||||
op = B_ENTRY_CREATED;
|
||||
} else if (oldStatus != MATCH_OK && newStatus != MATCH_OK) {
|
||||
// nothing has changed
|
||||
@@ -1517,6 +1525,7 @@ Query::LiveUpdate(Inode *inode,const char *attribute,int32 type,const uint8 *old
|
||||
if (type != B_STRING_TYPE || value == NULL)
|
||||
value = "";
|
||||
|
||||
send_notification(fPort,fToken,B_QUERY_UPDATE,op,fVolume->ID(),0,fVolume->ToVnode(inode->Parent()),0,inode->ID(),value);
|
||||
send_notification(fPort, fToken, B_QUERY_UPDATE, op, fVolume->ID(), 0,
|
||||
fVolume->ToVnode(inode->Parent()), 0, inode->ID(), value);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user