From a35c7bc81aec11e9720462d8258a0d3c41e2fac7 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 16 Jan 2014 09:06:01 +0100 Subject: [PATCH] db/upnp: move the LibUPnP instance to class UpnpDatabase Delete the object when closing the database. --- src/db/UpnpDatabasePlugin.cxx | 26 +++++++++------ src/db/upnp/ContentDirectoryService.cxx | 43 +++++++------------------ src/db/upnp/ContentDirectoryService.hxx | 17 +++++++--- src/db/upnp/Discovery.cxx | 12 ++----- src/db/upnp/Discovery.hxx | 5 ++- src/db/upnp/upnpplib.cxx | 14 -------- src/db/upnp/upnpplib.hxx | 9 ++---- 7 files changed, 49 insertions(+), 77 deletions(-) diff --git a/src/db/UpnpDatabasePlugin.cxx b/src/db/UpnpDatabasePlugin.cxx index 3c2ca72ff..e48b3cdd2 100644 --- a/src/db/UpnpDatabasePlugin.cxx +++ b/src/db/UpnpDatabasePlugin.cxx @@ -159,14 +159,18 @@ UpnpDatabase::Configure(const config_param &, Error &) bool UpnpDatabase::Open(Error &error) { - m_lib = LibUPnP::getLibUPnP(error); - if (!m_lib) + m_lib = new LibUPnP(); + if (!m_lib->ok()) { + error.Set(m_lib->GetInitError()); + delete m_lib; return false; + } - m_superdir = new UPnPDeviceDirectory(); + m_superdir = new UPnPDeviceDirectory(m_lib); if (!m_superdir->ok()) { error.Set(m_superdir->GetError()); delete m_superdir; + delete m_lib; return false; } @@ -182,7 +186,7 @@ UpnpDatabase::Close() { delete m_root; delete m_superdir; - // TBD decide what we do with the lib object + delete m_lib; } void @@ -285,7 +289,7 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server, return true; std::set searchcaps; - if (!server->getSearchCapabilities(searchcaps, error)) + if (!server->getSearchCapabilities(m_lib->getclh(), searchcaps, error)) return false; if (searchcaps.empty()) @@ -352,7 +356,9 @@ UpnpDatabase::SearchSongs(ContentDirectoryService* server, } } - return server->search(objid, cond.c_str(), dirbuf, error); + return server->search(m_lib->getclh(), + objid, cond.c_str(), dirbuf, + error); } static bool @@ -433,7 +439,7 @@ UpnpDatabase::ReadNode(ContentDirectoryService *server, Error &error) const { UPnPDirContent dirbuf; - if (!server->getMetadata(objid, dirbuf, error)) + if (!server->getMetadata(m_lib->getclh(), objid, dirbuf, error)) return false; if (dirbuf.objects.size() == 1) { @@ -484,10 +490,12 @@ UpnpDatabase::Namei(ContentDirectoryService* server, return true; } + const UpnpClient_Handle handle = m_lib->getclh(); + // Walk the path elements, read each directory and try to find the next one for (unsigned int i = 0; i < vpath.size(); i++) { UPnPDirContent dirbuf; - if (!server->readDir(objid.c_str(), dirbuf, error)) + if (!server->readDir(handle, objid.c_str(), dirbuf, error)) return false; // Look for the name in the sub-container list @@ -611,7 +619,7 @@ UpnpDatabase::VisitServer(ContentDirectoryService* server, and loop here, but it's not useful as mpd will only return data to the client when we're done anyway. */ UPnPDirContent dirbuf; - if (!server->readDir(objid.c_str(), dirbuf, error)) + if (!server->readDir(m_lib->getclh(), objid.c_str(), dirbuf, error)) return false; for (const auto &dirent : dirbuf.objects) { diff --git a/src/db/upnp/ContentDirectoryService.cxx b/src/db/upnp/ContentDirectoryService.cxx index b40f55c54..cb35f7a79 100644 --- a/src/db/upnp/ContentDirectoryService.cxx +++ b/src/db/upnp/ContentDirectoryService.cxx @@ -24,12 +24,10 @@ #include "ixmlwrap.hxx" #include "Directory.hxx" #include "Util.hxx" -#include "upnpplib.hxx" #include "util/Error.hxx" #include -#include #include ContentDirectoryService::ContentDirectoryService(const UPnPDevice &device, @@ -64,17 +62,12 @@ public: }; bool -ContentDirectoryService::readDirSlice(const char *objectId, int offset, +ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl, + const char *objectId, int offset, int count, UPnPDirContent &dirbuf, int *didreadp, int *totalp, Error &error) { - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return false; - - UpnpClient_Handle hdl = lib->getclh(); - IXML_Document *request(0); IXML_Document *response(0); DirBResFree cleaner(&request, &response); @@ -132,7 +125,8 @@ ContentDirectoryService::readDirSlice(const char *objectId, int offset, } bool -ContentDirectoryService::readDir(const char *objectId, +ContentDirectoryService::readDir(UpnpClient_Handle handle, + const char *objectId, UPnPDirContent &dirbuf, Error &error) { @@ -141,7 +135,7 @@ ContentDirectoryService::readDir(const char *objectId, while (offset < total) { int count; - if (!readDirSlice(objectId, offset, m_rdreqcnt, dirbuf, + if (!readDirSlice(handle, objectId, offset, m_rdreqcnt, dirbuf, &count, &total, error)) return false; @@ -152,17 +146,12 @@ ContentDirectoryService::readDir(const char *objectId, } bool -ContentDirectoryService::search(const char *objectId, +ContentDirectoryService::search(UpnpClient_Handle hdl, + const char *objectId, const char *ss, UPnPDirContent &dirbuf, Error &error) { - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return false; - - UpnpClient_Handle hdl = lib->getclh(); - IXML_Document *request(0); IXML_Document *response(0); @@ -226,15 +215,10 @@ ContentDirectoryService::search(const char *objectId, } bool -ContentDirectoryService::getSearchCapabilities(std::set &result, +ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl, + std::set &result, Error &error) { - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return false; - - UpnpClient_Handle hdl = lib->getclh(); - IXML_Document *request(0); IXML_Document *response(0); @@ -272,16 +256,11 @@ ContentDirectoryService::getSearchCapabilities(std::set &result, } bool -ContentDirectoryService::getMetadata(const char *objectId, +ContentDirectoryService::getMetadata(UpnpClient_Handle hdl, + const char *objectId, UPnPDirContent &dirbuf, Error &error) { - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return false; - - UpnpClient_Handle hdl = lib->getclh(); - IXML_Document *response(0); // Create request diff --git a/src/db/upnp/ContentDirectoryService.hxx b/src/db/upnp/ContentDirectoryService.hxx index 8fc28c382..63a13583f 100644 --- a/src/db/upnp/ContentDirectoryService.hxx +++ b/src/db/upnp/ContentDirectoryService.hxx @@ -20,6 +20,8 @@ #ifndef _UPNPDIR_HXX_INCLUDED_ #define _UPNPDIR_HXX_INCLUDED_ +#include + #include #include @@ -71,10 +73,12 @@ public: * @param objectId the UPnP object Id for the container. Root has Id "0" * @param[out] dirbuf stores the entries we read. */ - bool readDir(const char *objectId, UPnPDirContent &dirbuf, + bool readDir(UpnpClient_Handle handle, + const char *objectId, UPnPDirContent &dirbuf, Error &error); - bool readDirSlice(const char *objectId, int offset, + bool readDirSlice(UpnpClient_Handle handle, + const char *objectId, int offset, int count, UPnPDirContent& dirbuf, int *didread, int *total, Error &error); @@ -89,7 +93,8 @@ public: * section 2.5.5. Maybe we'll provide an easier way some day... * @param[out] dirbuf stores the entries we read. */ - bool search(const char *objectId, const char *searchstring, + bool search(UpnpClient_Handle handle, + const char *objectId, const char *searchstring, UPnPDirContent &dirbuf, Error &error); @@ -99,7 +104,8 @@ public: * @param[out] dirbuf stores the entries we read. At most one entry will be * returned. */ - bool getMetadata(const char *objectId, UPnPDirContent &dirbuf, + bool getMetadata(UpnpClient_Handle handle, + const char *objectId, UPnPDirContent &dirbuf, Error &error); /** Retrieve search capabilities @@ -107,7 +113,8 @@ public: * @param[out] result an empty vector: no search, or a single '*' element: * any tag can be used in a search, or a list of usable tag names. */ - bool getSearchCapabilities(std::set &result, + bool getSearchCapabilities(UpnpClient_Handle handle, + std::set &result, Error &error); /** Retrieve the "friendly name" for this server, useful for display. */ diff --git a/src/db/upnp/Discovery.cxx b/src/db/upnp/Discovery.cxx index 2824d4b56..a51b57a48 100644 --- a/src/db/upnp/Discovery.cxx +++ b/src/db/upnp/Discovery.cxx @@ -216,18 +216,14 @@ UPnPDeviceDirectory::expireDevices() search(); } -UPnPDeviceDirectory::UPnPDeviceDirectory() - :m_searchTimeout(2), m_lastSearch(0) +UPnPDeviceDirectory::UPnPDeviceDirectory(LibUPnP *_lib) + :lib(_lib), m_searchTimeout(2), m_lastSearch(0) { if (!discoveredQueue.start(1, discoExplorer, 0)) { error.Set(upnp_domain, "Discover work queue start failed"); return; } - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return; - lib->SetHandler([](Upnp_EventType type, void *event){ cluCallBack(type, event); }); @@ -243,10 +239,6 @@ UPnPDeviceDirectory::search() return true; m_lastSearch = now; - LibUPnP *lib = LibUPnP::getLibUPnP(error); - if (lib == nullptr) - return false; - // We search both for device and service just in case. int code = UpnpSearchAsync(lib->getclh(), m_searchTimeout, ContentDirectorySType, lib); diff --git a/src/db/upnp/Discovery.hxx b/src/db/upnp/Discovery.hxx index ddc7d2909..412307fd7 100644 --- a/src/db/upnp/Discovery.hxx +++ b/src/db/upnp/Discovery.hxx @@ -26,6 +26,7 @@ #include +class LibUPnP; class ContentDirectoryService; /** @@ -35,6 +36,8 @@ class ContentDirectoryService; * for now, but this could be made more general, by removing the filtering. */ class UPnPDeviceDirectory { + LibUPnP *const lib; + Error error; /** @@ -47,7 +50,7 @@ class UPnPDeviceDirectory { time_t m_lastSearch; public: - UPnPDeviceDirectory(); + UPnPDeviceDirectory(LibUPnP *_lib); UPnPDeviceDirectory(const UPnPDeviceDirectory &) = delete; UPnPDeviceDirectory& operator=(const UPnPDeviceDirectory &) = delete; diff --git a/src/db/upnp/upnpplib.cxx b/src/db/upnp/upnpplib.cxx index 508315b26..27b4e0564 100644 --- a/src/db/upnp/upnpplib.cxx +++ b/src/db/upnp/upnpplib.cxx @@ -27,20 +27,6 @@ static LibUPnP *theLib; -LibUPnP * -LibUPnP::getLibUPnP(Error &error) -{ - if (theLib == nullptr) - theLib = new LibUPnP; - - if (!theLib->ok()) { - error.Set(theLib->GetInitError()); - return nullptr; - } - - return theLib; -} - LibUPnP::LibUPnP() { auto code = UpnpInit(0, 0); diff --git a/src/db/upnp/upnpplib.hxx b/src/db/upnp/upnpplib.hxx index c1443624c..6759aa16d 100644 --- a/src/db/upnp/upnpplib.hxx +++ b/src/db/upnp/upnpplib.hxx @@ -35,19 +35,16 @@ class LibUPnP { Handler handler; + static int o_callback(Upnp_EventType, void *, void *); + +public: LibUPnP(); LibUPnP(const LibUPnP &) = delete; LibUPnP &operator=(const LibUPnP &) = delete; - static int o_callback(Upnp_EventType, void *, void *); - -public: ~LibUPnP(); - /** Retrieve the singleton LibUPnP object */ - static LibUPnP *getLibUPnP(Error &error); - /** Check state after initialization */ bool ok() const {