db/simple: use class ScopeDatabaseLock
This commit is contained in:
parent
7dd3b72a8c
commit
e31f0b8b0c
@ -72,7 +72,6 @@ db_load_internal(TextFile &file, Directory &music_root, Error &error)
|
||||
char *line;
|
||||
unsigned format = 0;
|
||||
bool found_charset = false, found_version = false;
|
||||
bool success;
|
||||
bool tags[TAG_NUM_OF_ITEM_TYPES];
|
||||
|
||||
/* get initial info */
|
||||
@ -152,9 +151,6 @@ db_load_internal(TextFile &file, Directory &music_root, Error &error)
|
||||
|
||||
LogDebug(db_domain, "reading DB");
|
||||
|
||||
db_lock();
|
||||
success = directory_load(file, music_root, error);
|
||||
db_unlock();
|
||||
|
||||
return success;
|
||||
const ScopeDatabaseLock protect;
|
||||
return directory_load(file, music_root, error);
|
||||
}
|
||||
|
@ -240,13 +240,13 @@ SimpleDatabase::GetSong(const char *uri, Error &error) const
|
||||
assert(prefixed_light_song == nullptr);
|
||||
assert(borrowed_song_count == 0);
|
||||
|
||||
db_lock();
|
||||
ScopeDatabaseLock protect;
|
||||
|
||||
auto r = root->LookupDirectory(uri);
|
||||
|
||||
if (r.directory->IsMount()) {
|
||||
/* pass the request to the mounted database */
|
||||
db_unlock();
|
||||
protect.unlock();
|
||||
|
||||
const LightSong *song =
|
||||
r.directory->mounted_database->GetSong(r.uri, error);
|
||||
@ -260,7 +260,6 @@ SimpleDatabase::GetSong(const char *uri, Error &error) const
|
||||
|
||||
if (r.uri == nullptr) {
|
||||
/* it's a directory */
|
||||
db_unlock();
|
||||
error.Format(db_domain, DB_NOT_FOUND,
|
||||
"No such song: %s", uri);
|
||||
return nullptr;
|
||||
@ -268,14 +267,13 @@ SimpleDatabase::GetSong(const char *uri, Error &error) const
|
||||
|
||||
if (strchr(r.uri, '/') != nullptr) {
|
||||
/* refers to a URI "below" the actual song */
|
||||
db_unlock();
|
||||
error.Format(db_domain, DB_NOT_FOUND,
|
||||
"No such song: %s", uri);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Song *song = r.directory->FindSong(r.uri);
|
||||
db_unlock();
|
||||
protect.unlock();
|
||||
if (song == nullptr) {
|
||||
error.Format(db_domain, DB_NOT_FOUND,
|
||||
"No such song: %s", uri);
|
||||
@ -367,15 +365,15 @@ SimpleDatabase::GetStats(const DatabaseSelection &selection,
|
||||
bool
|
||||
SimpleDatabase::Save(Error &error)
|
||||
{
|
||||
db_lock();
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
|
||||
LogDebug(simple_db_domain, "removing empty directories from DB");
|
||||
root->PruneEmpty();
|
||||
LogDebug(simple_db_domain, "removing empty directories from DB");
|
||||
root->PruneEmpty();
|
||||
|
||||
LogDebug(simple_db_domain, "sorting DB");
|
||||
root->Sort();
|
||||
|
||||
db_unlock();
|
||||
LogDebug(simple_db_domain, "sorting DB");
|
||||
root->Sort();
|
||||
}
|
||||
|
||||
LogDebug(simple_db_domain, "writing DB");
|
||||
|
||||
|
@ -39,6 +39,27 @@
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
static Directory *
|
||||
LockFindChild(Directory &directory, const char *name)
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
return directory.FindChild(name);
|
||||
}
|
||||
|
||||
static Directory *
|
||||
LockMakeChild(Directory &directory, const char *name)
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
return directory.MakeChild(name);
|
||||
}
|
||||
|
||||
static Song *
|
||||
LockFindSong(Directory &directory, const char *name)
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
return directory.FindSong(name);
|
||||
}
|
||||
|
||||
void
|
||||
UpdateWalk::UpdateArchiveTree(Directory &directory, const char *name)
|
||||
{
|
||||
@ -46,11 +67,9 @@ UpdateWalk::UpdateArchiveTree(Directory &directory, const char *name)
|
||||
if (tmp) {
|
||||
const std::string child_name(name, tmp);
|
||||
//add dir is not there already
|
||||
db_lock();
|
||||
Directory *subdir =
|
||||
directory.MakeChild(child_name.c_str());
|
||||
Directory *subdir = LockMakeChild(directory,
|
||||
child_name.c_str());
|
||||
subdir->device = DEVICE_INARCHIVE;
|
||||
db_unlock();
|
||||
|
||||
//create directories first
|
||||
UpdateArchiveTree(*subdir, tmp + 1);
|
||||
@ -62,15 +81,14 @@ UpdateWalk::UpdateArchiveTree(Directory &directory, const char *name)
|
||||
}
|
||||
|
||||
//add file
|
||||
db_lock();
|
||||
Song *song = directory.FindSong(name);
|
||||
db_unlock();
|
||||
Song *song = LockFindSong(directory, name);
|
||||
if (song == nullptr) {
|
||||
song = Song::LoadFile(storage, name, directory);
|
||||
if (song != nullptr) {
|
||||
db_lock();
|
||||
directory.AddSong(song);
|
||||
db_unlock();
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
directory.AddSong(song);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
FormatDefault(update_domain, "added %s/%s",
|
||||
@ -108,9 +126,7 @@ UpdateWalk::UpdateArchiveFile(Directory &parent, const char *name,
|
||||
const StorageFileInfo &info,
|
||||
const ArchivePlugin &plugin)
|
||||
{
|
||||
db_lock();
|
||||
Directory *directory = parent.FindChild(name);
|
||||
db_unlock();
|
||||
Directory *directory = LockFindChild(parent, name);
|
||||
|
||||
if (directory != nullptr && directory->mtime == info.mtime &&
|
||||
!walk_discard)
|
||||
@ -139,12 +155,12 @@ UpdateWalk::UpdateArchiveFile(Directory &parent, const char *name,
|
||||
if (directory == nullptr) {
|
||||
FormatDebug(update_domain,
|
||||
"creating archive directory: %s", name);
|
||||
db_lock();
|
||||
|
||||
const ScopeDatabaseLock protect;
|
||||
directory = parent.CreateChild(name);
|
||||
/* mark this directory as archive (we use device for
|
||||
this) */
|
||||
directory->device = DEVICE_INARCHIVE;
|
||||
db_unlock();
|
||||
}
|
||||
|
||||
directory->mtime = info.mtime;
|
||||
|
@ -78,16 +78,16 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
|
||||
return false;
|
||||
const DecoderPlugin &plugin = *_plugin;
|
||||
|
||||
db_lock();
|
||||
Directory *contdir = MakeDirectoryIfModified(directory, name, info);
|
||||
if (contdir == nullptr) {
|
||||
/* not modified */
|
||||
db_unlock();
|
||||
return true;
|
||||
}
|
||||
Directory *contdir;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
contdir = MakeDirectoryIfModified(directory, name, info);
|
||||
if (contdir == nullptr)
|
||||
/* not modified */
|
||||
return true;
|
||||
|
||||
contdir->device = DEVICE_CONTAINER;
|
||||
db_unlock();
|
||||
contdir->device = DEVICE_CONTAINER;
|
||||
}
|
||||
|
||||
const auto pathname = storage.MapFS(contdir->GetPath());
|
||||
if (pathname.IsNull()) {
|
||||
@ -116,9 +116,10 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
|
||||
|
||||
tag_builder.Commit(song->tag);
|
||||
|
||||
db_lock();
|
||||
contdir->AddSong(song);
|
||||
db_unlock();
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
contdir->AddSong(song);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
|
||||
|
@ -50,9 +50,8 @@ DatabaseEditor::DeleteSong(Directory &dir, Song *del)
|
||||
void
|
||||
DatabaseEditor::LockDeleteSong(Directory &parent, Song *song)
|
||||
{
|
||||
db_lock();
|
||||
const ScopeDatabaseLock protect;
|
||||
DeleteSong(parent, song);
|
||||
db_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,17 +86,17 @@ DatabaseEditor::DeleteDirectory(Directory *directory)
|
||||
void
|
||||
DatabaseEditor::LockDeleteDirectory(Directory *directory)
|
||||
{
|
||||
db_lock();
|
||||
const ScopeDatabaseLock protect;
|
||||
DeleteDirectory(directory);
|
||||
db_unlock();
|
||||
}
|
||||
|
||||
bool
|
||||
DatabaseEditor::DeleteNameIn(Directory &parent, const char *name)
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
|
||||
bool modified = false;
|
||||
|
||||
db_lock();
|
||||
Directory *directory = parent.FindChild(name);
|
||||
|
||||
if (directory != nullptr) {
|
||||
@ -113,7 +112,5 @@ DatabaseEditor::DeleteNameIn(Directory &parent, const char *name)
|
||||
|
||||
parent.playlists.erase(name);
|
||||
|
||||
db_unlock();
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
@ -80,9 +80,11 @@ UpdateService::CancelMount(const char *uri)
|
||||
/* determine which (mounted) database will be updated and what
|
||||
storage will be scanned */
|
||||
|
||||
db_lock();
|
||||
const auto lr = db.GetRoot().LookupDirectory(uri);
|
||||
db_unlock();
|
||||
Directory::LookupResult lr;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
lr = db.GetRoot().LookupDirectory(uri);
|
||||
}
|
||||
|
||||
if (!lr.directory->IsMount())
|
||||
return;
|
||||
@ -188,9 +190,12 @@ UpdateService::Enqueue(const char *path, bool discard)
|
||||
SimpleDatabase *db2;
|
||||
Storage *storage2;
|
||||
|
||||
db_lock();
|
||||
const auto lr = db.GetRoot().LookupDirectory(path);
|
||||
db_unlock();
|
||||
Directory::LookupResult lr;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
lr = db.GetRoot().LookupDirectory(path);
|
||||
}
|
||||
|
||||
if (lr.directory->IsMount()) {
|
||||
/* follow the mountpoint, update the mounted
|
||||
database */
|
||||
|
@ -35,9 +35,11 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
|
||||
const char *name, const char *suffix,
|
||||
const StorageFileInfo &info)
|
||||
{
|
||||
db_lock();
|
||||
Song *song = directory.FindSong(name);
|
||||
db_unlock();
|
||||
Song *song;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
song = directory.FindSong(name);
|
||||
}
|
||||
|
||||
if (!directory_child_access(storage, directory, name, R_OK)) {
|
||||
FormatError(update_domain,
|
||||
@ -69,9 +71,10 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
|
||||
return;
|
||||
}
|
||||
|
||||
db_lock();
|
||||
directory.AddSong(song);
|
||||
db_unlock();
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
directory.AddSong(song);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
FormatDefault(update_domain, "added %s/%s",
|
||||
|
@ -78,7 +78,7 @@ inline void
|
||||
UpdateWalk::RemoveExcludedFromDirectory(Directory &directory,
|
||||
const ExcludeList &exclude_list)
|
||||
{
|
||||
db_lock();
|
||||
const ScopeDatabaseLock protect;
|
||||
|
||||
directory.ForEachChildSafe([&](Directory &child){
|
||||
const auto name_fs =
|
||||
@ -99,8 +99,6 @@ UpdateWalk::RemoveExcludedFromDirectory(Directory &directory,
|
||||
modified = true;
|
||||
}
|
||||
});
|
||||
|
||||
db_unlock();
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -129,9 +127,8 @@ UpdateWalk::PurgeDeletedFromDirectory(Directory &directory)
|
||||
i != end;) {
|
||||
if (!directory_child_is_regular(storage, directory,
|
||||
i->name.c_str())) {
|
||||
db_lock();
|
||||
const ScopeDatabaseLock protect;
|
||||
i = directory.playlists.erase(i);
|
||||
db_unlock();
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
@ -198,10 +195,9 @@ UpdateWalk::UpdatePlaylistFile(Directory &directory,
|
||||
|
||||
PlaylistInfo pi(name, info.mtime);
|
||||
|
||||
db_lock();
|
||||
const ScopeDatabaseLock protect;
|
||||
if (directory.playlists.UpdateOrInsert(std::move(pi)))
|
||||
modified = true;
|
||||
db_unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -232,9 +228,11 @@ UpdateWalk::UpdateDirectoryChild(Directory &directory,
|
||||
info.inode, info.device))
|
||||
return;
|
||||
|
||||
db_lock();
|
||||
Directory *subdir = directory.MakeChild(name);
|
||||
db_unlock();
|
||||
Directory *subdir;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
subdir = directory.MakeChild(name);
|
||||
}
|
||||
|
||||
assert(&directory == subdir->parent);
|
||||
|
||||
@ -393,9 +391,11 @@ UpdateWalk::DirectoryMakeChildChecked(Directory &parent,
|
||||
const char *uri_utf8,
|
||||
const char *name_utf8)
|
||||
{
|
||||
db_lock();
|
||||
Directory *directory = parent.FindChild(name_utf8);
|
||||
db_unlock();
|
||||
Directory *directory;
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
directory = parent.FindChild(name_utf8);
|
||||
}
|
||||
|
||||
if (directory != nullptr) {
|
||||
if (directory->IsMount())
|
||||
@ -414,13 +414,14 @@ UpdateWalk::DirectoryMakeChildChecked(Directory &parent,
|
||||
|
||||
/* if we're adding directory paths, make sure to delete filenames
|
||||
with potentially the same name */
|
||||
db_lock();
|
||||
Song *conflicting = parent.FindSong(name_utf8);
|
||||
if (conflicting)
|
||||
editor.DeleteSong(parent, conflicting);
|
||||
{
|
||||
const ScopeDatabaseLock protect;
|
||||
Song *conflicting = parent.FindSong(name_utf8);
|
||||
if (conflicting)
|
||||
editor.DeleteSong(parent, conflicting);
|
||||
|
||||
directory = parent.CreateChild(name_utf8);
|
||||
db_unlock();
|
||||
directory = parent.CreateChild(name_utf8);
|
||||
}
|
||||
|
||||
directory_set_stat(*directory, info);
|
||||
return directory;
|
||||
|
Loading…
Reference in New Issue
Block a user