Tracker: Use BStrings and BObjectList in handling MostUsedNames.

Avoids some potential races.
This commit is contained in:
Augustin Cavalier
2025-02-27 12:56:21 -05:00
parent e1bdecd0d7
commit ecef10e688
+25 -33
View File
@@ -143,18 +143,18 @@ public:
int32 maxCount = 5); int32 maxCount = 5);
~MostUsedNames(); ~MostUsedNames();
bool ObtainList(BList* list); bool ObtainList(BStringList* list);
void ReleaseList(); void ReleaseList();
void AddName(const char*); void AddName(const BString&);
protected: protected:
struct list_entry { struct list_entry {
char* name; BString name;
int32 count; int32 count;
}; };
static int CompareNames(const void* a, const void* b); static int CompareNames(const list_entry* a, const list_entry* b);
void LoadList(); void LoadList();
void UpdateList(); void UpdateList();
@@ -162,7 +162,7 @@ protected:
const char* fDirectory; const char* fDirectory;
bool fLoaded; bool fLoaded;
mutable Benaphore fLock; mutable Benaphore fLock;
BList fList; BObjectList<list_entry> fList;
int32 fCount; int32 fCount;
}; };
@@ -2391,11 +2391,11 @@ FindPanel::AddMimeTypesToMenu()
TTracker* tracker = dynamic_cast<TTracker*>(be_app); TTracker* tracker = dynamic_cast<TTracker*>(be_app);
ASSERT(tracker != NULL); ASSERT(tracker != NULL);
BList list; BStringList list;
if (tracker != NULL && gMostUsedMimeTypes.ObtainList(&list)) { if (tracker != NULL && gMostUsedMimeTypes.ObtainList(&list)) {
int32 count = 0; int32 count = 0;
for (int32 index = 0; index < list.CountItems(); index++) { for (int32 index = 0; index < list.CountStrings(); index++) {
const char* name = (const char*)list.ItemAt(index); BString name = list.StringAt(index);
MimeTypeList* mimeTypes = tracker->MimeTypes(); MimeTypeList* mimeTypes = tracker->MimeTypes();
if (mimeTypes != NULL) { if (mimeTypes != NULL) {
@@ -3839,9 +3839,7 @@ MostUsedNames::~MostUsedNames()
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (file.InitCheck() == B_OK) { if (file.InitCheck() == B_OK) {
for (int32 i = 0; i < fList.CountItems(); i++) { for (int32 i = 0; i < fList.CountItems(); i++) {
list_entry* entry = static_cast<list_entry*>(fList.ItemAt(i)); list_entry* entry = fList.ItemAt(i);
char line[B_FILE_NAME_LENGTH + 5];
// limit upper bound to react more dynamically to changes // limit upper bound to react more dynamically to changes
if (--entry->count > 20) if (--entry->count > 20)
@@ -3852,8 +3850,9 @@ MostUsedNames::~MostUsedNames()
if (entry->count < -10 && i > 0) if (entry->count < -10 && i > 0)
continue; continue;
sprintf(line, "%" B_PRId32 " %s\n", entry->count, entry->name); BString line;
if (file.Write(line, strlen(line)) < B_OK) line.SetToFormat("%" B_PRId32 " %s\n", entry->count, entry->name.String());
if (file.Write(line.String(), line.Length()) < B_OK)
break; break;
} }
} }
@@ -3862,15 +3861,14 @@ MostUsedNames::~MostUsedNames()
// free data // free data
for (int32 i = fList.CountItems(); i-- > 0;) { for (int32 i = fList.CountItems(); i-- > 0;) {
list_entry* entry = static_cast<list_entry*>(fList.ItemAt(i)); list_entry* entry = fList.ItemAt(i);
free(entry->name);
delete entry; delete entry;
} }
} }
bool bool
MostUsedNames::ObtainList(BList* list) MostUsedNames::ObtainList(BStringList* list)
{ {
if (list == NULL) if (list == NULL)
return false; return false;
@@ -3882,11 +3880,11 @@ MostUsedNames::ObtainList(BList* list)
list->MakeEmpty(); list->MakeEmpty();
for (int32 i = 0; i < fCount; i++) { for (int32 i = 0; i < fCount; i++) {
list_entry* entry = static_cast<list_entry*>(fList.ItemAt(i)); list_entry* entry = fList.ItemAt(i);
if (entry == NULL) if (entry == NULL)
return true; return true;
list->AddItem(entry->name); list->Add(entry->name);
} }
return true; return true;
} }
@@ -3900,7 +3898,7 @@ MostUsedNames::ReleaseList()
void void
MostUsedNames::AddName(const char* name) MostUsedNames::AddName(const BString& name)
{ {
fLock.Lock(); fLock.Lock();
@@ -3913,12 +3911,10 @@ MostUsedNames::AddName(const char* name)
list_entry* entry = NULL; list_entry* entry = NULL;
if (fList.CountItems() > fCount * 2) { if (fList.CountItems() > fCount * 2) {
entry = static_cast<list_entry*>( entry = fList.RemoveItemAt(fList.CountItems() - 1);
fList.RemoveItem(fList.CountItems() - 1));
// is this the name we want to add here? // is this the name we want to add here?
if (strcmp(name, entry->name)) { if (name == entry->name) {
free(entry->name);
delete entry; delete entry;
entry = NULL; entry = NULL;
} else } else
@@ -3926,16 +3922,15 @@ MostUsedNames::AddName(const char* name)
} }
if (entry == NULL) { if (entry == NULL) {
for (int32 i = 0; for (int32 i = 0; (entry = fList.ItemAt(i)) != NULL; i++) {
(entry = static_cast<list_entry*>(fList.ItemAt(i))) != NULL; i++) { if (entry->name == name)
if (strcmp(entry->name, name) == 0)
break; break;
} }
} }
if (entry == NULL) { if (entry == NULL) {
entry = new list_entry; entry = new list_entry;
entry->name = strdup(name); entry->name = name;
entry->count = 1; entry->count = 1;
fList.AddItem(entry); fList.AddItem(entry);
@@ -3950,13 +3945,10 @@ MostUsedNames::AddName(const char* name)
int int
MostUsedNames::CompareNames(const void* a,const void* b) MostUsedNames::CompareNames(const list_entry* entryA, const list_entry* entryB)
{ {
list_entry* entryA = *(list_entry**)a;
list_entry* entryB = *(list_entry**)b;
if (entryA->count == entryB->count) if (entryA->count == entryB->count)
return strcasecmp(entryA->name,entryB->name); return entryA->name.ICompare(entryB->name);
return entryB->count - entryA->count; return entryB->count - entryA->count;
} }
@@ -3994,7 +3986,7 @@ MostUsedNames::LoadList()
continue; continue;
list_entry* entry = new list_entry; list_entry* entry = new list_entry;
entry->name = strdup(name); entry->name = name;
entry->count = count; entry->count = count;
fList.AddItem(entry); fList.AddItem(entry);