diff options
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 |