db/Plugin: use std::unique_ptr<> to manage Database pointers

This commit is contained in:
Max Kellermann 2019-02-20 20:32:11 +01:00
parent 2125e3ed57
commit 6c28adbcd2
15 changed files with 93 additions and 73 deletions

View File

@ -188,7 +188,7 @@ glue_db_init_and_load(const ConfigData &config)
instance->database =
CreateConfiguredDatabase(config, instance->event_loop,
instance->io_thread.GetEventLoop(),
*instance);
*instance).release();
if (instance->database == nullptr)
return true;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -19,6 +19,7 @@
#include "Configured.hxx"
#include "DatabaseGlue.hxx"
#include "Interface.hxx"
#include "config/Data.hxx"
#include "config/Param.hxx"
#include "config/Block.hxx"
@ -26,7 +27,7 @@
#include "fs/StandardDirectory.hxx"
#include "util/RuntimeError.hxx"
Database *
DatabasePtr
CreateConfiguredDatabase(const ConfigData &config,
EventLoop &main_event_loop, EventLoop &io_event_loop,
DatabaseListener &listener)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -20,10 +20,11 @@
#ifndef MPD_DB_CONFIG_HXX
#define MPD_DB_CONFIG_HXX
#include "Ptr.hxx"
struct ConfigData;
class EventLoop;
class DatabaseListener;
class Database;
/**
* Read database configuration settings and create a #Database
@ -32,7 +33,7 @@ class Database;
*
* Throws #std::runtime_error on error.
*/
Database *
DatabasePtr
CreateConfiguredDatabase(const ConfigData &config,
EventLoop &main_event_loop, EventLoop &io_event_loop,
DatabaseListener &listener);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -18,13 +18,14 @@
*/
#include "DatabaseGlue.hxx"
#include "Interface.hxx"
#include "Registry.hxx"
#include "DatabaseError.hxx"
#include "util/RuntimeError.hxx"
#include "config/Block.hxx"
#include "DatabasePlugin.hxx"
Database *
DatabasePtr
DatabaseGlobalInit(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -20,12 +20,11 @@
#ifndef MPD_DATABASE_GLUE_HXX
#define MPD_DATABASE_GLUE_HXX
#include "util/Compiler.h"
#include "Ptr.hxx"
struct ConfigBlock;
class EventLoop;
class DatabaseListener;
class Database;
/**
* Initialize the database library.
@ -34,7 +33,7 @@ class Database;
*
* @param block the database configuration block
*/
Database *
DatabasePtr
DatabaseGlobalInit(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -26,10 +26,11 @@
#ifndef MPD_DATABASE_PLUGIN_HXX
#define MPD_DATABASE_PLUGIN_HXX
#include "Ptr.hxx"
struct ConfigBlock;
class EventLoop;
class DatabaseListener;
class Database;
struct DatabasePlugin {
/**
@ -52,10 +53,10 @@ struct DatabasePlugin {
* @param io_event_loop the #EventLoop running on the
* #EventThread, i.e. the one used for background I/O
*/
Database *(*create)(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
DatabasePtr (*create)(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
constexpr bool RequireStorage() const {
return flags & FLAG_REQUIRE_STORAGE;

29
src/db/Ptr.hxx Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_DATABASE_PTR_HXX
#define MPD_DATABASE_PTR_HXX
#include <memory>
class Database;
typedef std::unique_ptr<Database> DatabasePtr;
#endif

View File

@ -112,10 +112,10 @@ public:
ProxyDatabase(EventLoop &_loop, DatabaseListener &_listener,
const ConfigBlock &block);
static Database *Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
static DatabasePtr Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
void Open() override;
void Close() noexcept override;
@ -440,12 +440,12 @@ ProxyDatabase::ProxyDatabase(EventLoop &_loop, DatabaseListener &_listener,
{
}
Database *
DatabasePtr
ProxyDatabase::Create(EventLoop &loop, EventLoop &,
DatabaseListener &listener,
const ConfigBlock &block)
{
return new ProxyDatabase(loop, listener, block);
return std::make_unique<ProxyDatabase>(loop, listener, block);
}
void

View File

@ -45,8 +45,6 @@ Directory::Directory(std::string &&_path_utf8, Directory *_parent) noexcept
Directory::~Directory() noexcept
{
delete mounted_database;
songs.clear_and_dispose(Song::Disposer());
children.clear_and_dispose(DeleteDisposer());
}

View File

@ -23,6 +23,7 @@
#include "util/Compiler.h"
#include "db/Visitor.hxx"
#include "db/PlaylistVector.hxx"
#include "db/Ptr.hxx"
#include "Song.hxx"
#include <boost/intrusive/list.hpp>
@ -43,7 +44,6 @@ static constexpr unsigned DEVICE_INARCHIVE = -1;
static constexpr unsigned DEVICE_CONTAINER = -2;
class SongFilter;
class Database;
struct Directory {
static constexpr auto link_mode = boost::intrusive::normal_link;
@ -96,7 +96,7 @@ struct Directory {
* If this is not nullptr, then this directory does not really
* exist, but is a mount point for another #Database.
*/
Database *mounted_database = nullptr;
DatabasePtr mounted_database;
public:
Directory(std::string &&_path_utf8, Directory *_parent) noexcept;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -84,12 +84,12 @@ inline SimpleDatabase::SimpleDatabase(AllocatedPath &&_path,
prefixed_light_song(nullptr) {
}
Database *
DatabasePtr
SimpleDatabase::Create(EventLoop &, EventLoop &,
gcc_unused DatabaseListener &listener,
const ConfigBlock &block)
{
return new SimpleDatabase(block);
return std::make_unique<SimpleDatabase>(block);
}
void
@ -390,13 +390,13 @@ SimpleDatabase::Save()
}
void
SimpleDatabase::Mount(const char *uri, Database *db)
SimpleDatabase::Mount(const char *uri, DatabasePtr db)
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
assert(uri != nullptr);
assert(db != nullptr);
#endif
assert(db != nullptr);
assert(*uri != 0);
ScopeDatabaseLock protect;
@ -411,7 +411,7 @@ SimpleDatabase::Mount(const char *uri, Database *db)
"Parent not found");
Directory *mnt = r.directory->CreateChild(r.uri);
mnt->mounted_database = db;
mnt->mounted_database = std::move(db);
}
static constexpr bool
@ -441,27 +441,21 @@ SimpleDatabase::Mount(const char *local_uri, const char *storage_uri)
#ifndef ENABLE_ZLIB
constexpr bool compress = false;
#endif
auto db = new SimpleDatabase(cache_path / name_fs,
compress);
try {
db->Open();
} catch (...) {
delete db;
throw;
}
auto db = std::make_unique<SimpleDatabase>(cache_path / name_fs,
compress);
db->Open();
// TODO: update the new database instance?
try {
Mount(local_uri, db);
Mount(local_uri, std::move(db));
} catch (...) {
db->Close();
delete db;
throw;
}
}
inline Database *
inline DatabasePtr
SimpleDatabase::LockUmountSteal(const char *uri) noexcept
{
ScopeDatabaseLock protect;
@ -470,8 +464,7 @@ SimpleDatabase::LockUmountSteal(const char *uri) noexcept
if (r.uri != nullptr || !r.directory->IsMount())
return nullptr;
Database *db = r.directory->mounted_database;
r.directory->mounted_database = nullptr;
auto db = std::move(r.directory->mounted_database);
r.directory->Delete();
return db;
@ -480,12 +473,11 @@ SimpleDatabase::LockUmountSteal(const char *uri) noexcept
bool
SimpleDatabase::Unmount(const char *uri) noexcept
{
Database *db = LockUmountSteal(uri);
auto db = LockUmountSteal(uri);
if (db == nullptr)
return false;
db->Close();
delete db;
return true;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -21,6 +21,7 @@
#define MPD_SIMPLE_DATABASE_PLUGIN_HXX
#include "db/Interface.hxx"
#include "db/Ptr.hxx"
#include "fs/AllocatedPath.hxx"
#include "song/LightSong.hxx"
#include "util/Manual.hxx"
@ -68,15 +69,14 @@ class SimpleDatabase : public Database {
mutable unsigned borrowed_song_count;
#endif
public:
SimpleDatabase(const ConfigBlock &block);
SimpleDatabase(AllocatedPath &&_path, bool _compress) noexcept;
public:
static Database *Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
static DatabasePtr Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block);
gcc_pure
Directory &GetRoot() noexcept {
@ -99,7 +99,7 @@ public:
* success, this object gains ownership of the given #Database
*/
gcc_nonnull_all
void Mount(const char *uri, Database *db);
void Mount(const char *uri, DatabasePtr db);
/**
* Throws #std::runtime_error on error.
@ -142,7 +142,7 @@ private:
*/
void Load();
Database *LockUmountSteal(const char *uri) noexcept;
DatabasePtr LockUmountSteal(const char *uri) noexcept;
};
extern const DatabasePlugin simple_db_plugin;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@ -82,10 +82,10 @@ public:
:Database(upnp_db_plugin),
event_loop(_event_loop) {}
static Database *Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block) noexcept;
static DatabasePtr Create(EventLoop &main_event_loop,
EventLoop &io_event_loop,
DatabaseListener &listener,
const ConfigBlock &block) noexcept;
void Open() override;
void Close() noexcept override;
@ -146,12 +146,12 @@ private:
const UPnPDirObject& dirent) const;
};
Database *
DatabasePtr
UpnpDatabase::Create(EventLoop &, EventLoop &io_event_loop,
gcc_unused DatabaseListener &listener,
const ConfigBlock &) noexcept
{
return new UpnpDatabase(io_event_loop);
return std::make_unique<UpnpDatabase>(io_event_loop);
}
void

View File

@ -94,7 +94,7 @@ UpdateService::CancelMount(const char *uri)
cancel_current = next.IsDefined() && next.storage == storage2;
}
if (auto *db2 = dynamic_cast<SimpleDatabase *>(lr.directory->mounted_database)) {
if (auto *db2 = dynamic_cast<SimpleDatabase *>(lr.directory->mounted_database.get())) {
queue.Erase(*db2);
cancel_current |= next.IsDefined() && next.db == db2;
}
@ -188,7 +188,7 @@ UpdateService::Enqueue(const char *path, bool discard)
/* follow the mountpoint, update the mounted
database */
db2 = dynamic_cast<SimpleDatabase *>(lr.directory->mounted_database);
db2 = dynamic_cast<SimpleDatabase *>(lr.directory->mounted_database.get());
if (db2 == nullptr)
throw std::runtime_error("Cannot update this type of database");

View File

@ -133,15 +133,13 @@ try {
if (path != nullptr)
block.AddBlockParam("path", path->value, path->line);
Database *db = plugin->create(init.GetEventLoop(),
init.GetEventLoop(),
database_listener, block);
AtScopeExit(db) { delete db; };
auto db = plugin->create(init.GetEventLoop(),
init.GetEventLoop(),
database_listener, block);
db->Open();
AtScopeExit(db) { db->Close(); };
AtScopeExit(&db) { db->Close(); };
const DatabaseSelection selection("", true);