aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/upnp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/upnp/ClientInit.cxx (renamed from src/lib/upnp/upnpplib.cxx)73
-rw-r--r--src/lib/upnp/ClientInit.hxx (renamed from src/lib/upnp/upnpplib.hxx)42
2 files changed, 62 insertions, 53 deletions
diff --git a/src/lib/upnp/upnpplib.cxx b/src/lib/upnp/ClientInit.cxx
index d36fc3593..77d9cf03d 100644
--- a/src/lib/upnp/upnpplib.cxx
+++ b/src/lib/upnp/ClientInit.cxx
@@ -18,31 +18,21 @@
*/
#include "config.h"
-#include "upnpplib.hxx"
+#include "ClientInit.hxx"
+#include "Init.hxx"
#include "Callback.hxx"
#include "Domain.hxx"
-#include "Init.hxx"
-#include "Log.hxx"
+#include "thread/Mutex.hxx"
+#include "util/Error.hxx"
#include <upnp/upnptools.h>
-LibUPnP::LibUPnP()
-{
- if (!UpnpGlobalInit(init_error))
- return;
-
- auto code = UpnpRegisterClient(o_callback, nullptr, &m_clh);
- if (code != UPNP_E_SUCCESS) {
- UpnpGlobalFinish();
- init_error.Format(upnp_domain, code,
- "UpnpRegisterClient() failed: %s",
- UpnpGetErrorMessage(code));
- return;
- }
-}
+static Mutex upnp_client_init_mutex;
+static unsigned upnp_client_ref;
+static UpnpClient_Handle upnp_client_handle;
-int
-LibUPnP::o_callback(Upnp_EventType et, void* evp, void* cookie)
+static int
+UpnpClientCallback(Upnp_EventType et, void *evp, void *cookie)
{
if (cookie == nullptr)
/* this is the cookie passed to UpnpRegisterClient();
@@ -54,7 +44,50 @@ LibUPnP::o_callback(Upnp_EventType et, void* evp, void* cookie)
return callback.Invoke(et, evp);
}
-LibUPnP::~LibUPnP()
+static bool
+DoInit(Error &error)
+{
+ auto code = UpnpRegisterClient(UpnpClientCallback, nullptr,
+ &upnp_client_handle);
+ if (code != UPNP_E_SUCCESS) {
+ error.Format(upnp_domain, code,
+ "UpnpRegisterClient() failed: %s",
+ UpnpGetErrorMessage(code));
+ return false;
+ }
+
+ return true;
+}
+
+bool
+UpnpClientGlobalInit(UpnpClient_Handle &handle, Error &error)
+{
+ if (!UpnpGlobalInit(error))
+ return false;
+
+ upnp_client_init_mutex.lock();
+ bool success = upnp_client_ref > 0 || DoInit(error);
+ upnp_client_init_mutex.unlock();
+
+ if (success) {
+ ++upnp_client_ref;
+ handle = upnp_client_handle;
+ } else
+ UpnpGlobalFinish();
+
+ return success;
+}
+
+void
+UpnpClientGlobalFinish()
{
+ upnp_client_init_mutex.lock();
+
+ assert(upnp_client_ref > 0);
+ if (--upnp_client_ref == 0)
+ UpnpUnRegisterClient(upnp_client_handle);
+
+ upnp_client_init_mutex.unlock();
+
UpnpGlobalFinish();
}
diff --git a/src/lib/upnp/upnpplib.hxx b/src/lib/upnp/ClientInit.hxx
index cd1762ec4..645e64ca6 100644
--- a/src/lib/upnp/upnpplib.hxx
+++ b/src/lib/upnp/ClientInit.hxx
@@ -17,43 +17,19 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef _LIBUPNP_H_X_INCLUDED_
-#define _LIBUPNP_H_X_INCLUDED_
+#ifndef MPD_UPNP_CLIENT_INIT_HXX
+#define MPD_UPNP_CLIENT_INIT_HXX
-#include "util/Error.hxx"
+#include "check.h"
#include <upnp/upnp.h>
-/** Our link to libupnp. Initialize and keep the handle around */
-class LibUPnP {
- Error init_error;
- UpnpClient_Handle m_clh;
+class Error;
- static int o_callback(Upnp_EventType, void *, void *);
+bool
+UpnpClientGlobalInit(UpnpClient_Handle &handle, Error &error);
-public:
- LibUPnP();
+void
+UpnpClientGlobalFinish();
- LibUPnP(const LibUPnP &) = delete;
- LibUPnP &operator=(const LibUPnP &) = delete;
-
- ~LibUPnP();
-
- /** Check state after initialization */
- bool ok() const
- {
- return !init_error.IsDefined();
- }
-
- /** Retrieve init error if state not ok */
- const Error &GetInitError() const {
- return init_error;
- }
-
- UpnpClient_Handle getclh()
- {
- return m_clh;
- }
-};
-
-#endif /* _LIBUPNP.H_X_INCLUDED_ */
+#endif