From a35c7bc81aec11e9720462d8258a0d3c41e2fac7 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Thu, 16 Jan 2014 09:06:01 +0100
Subject: db/upnp: move the LibUPnP instance to class UpnpDatabase

Delete the object when closing the database.
---
 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 +++----
 6 files changed, 32 insertions(+), 68 deletions(-)

(limited to 'src/db/upnp')

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 <stdio.h>
 
-#include <upnp/upnp.h>
 #include <upnp/upnptools.h>
 
 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<std::string> &result,
+ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl,
+					       std::set<std::string> &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<std::string> &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 <upnp/upnp.h>
+
 #include <string>
 #include <set>
 
@@ -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<std::string> &result,
+	bool getSearchCapabilities(UpnpClient_Handle handle,
+				   std::set<std::string> &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 <time.h>
 
+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
 	{
-- 
cgit v1.2.3