zeroconf/avahi/Init: return a std::unique_ptr<AvahiHelper>

This commit is contained in:
Max Kellermann 2021-02-24 14:27:05 +01:00
parent b01ef1b9a6
commit 975d5be046
5 changed files with 64 additions and 42 deletions

View File

@ -18,7 +18,6 @@
*/
#include "Glue.hxx"
#include "avahi/Init.hxx"
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "Listen.hxx"
@ -26,6 +25,10 @@
#include "Log.hxx"
#include "util/Compiler.h"
#ifdef HAVE_AVAHI
#include "avahi/Helper.hxx"
#endif
#ifdef HAVE_BONJOUR
#include "Bonjour.hxx"
#endif
@ -52,6 +55,10 @@ static constexpr Domain zeroconf_domain("zeroconf");
static int zeroconfEnabled;
#ifdef HAVE_AVAHI
static std::unique_ptr<AvahiHelper> avahi_helper;
#endif
#ifdef HAVE_BONJOUR
static std::unique_ptr<BonjourHelper> bonjour_helper;
#endif
@ -89,7 +96,7 @@ ZeroconfInit(const ConfigData &config, [[maybe_unused]] EventLoop &loop)
}
#ifdef HAVE_AVAHI
AvahiInit(loop, serviceName, listen_port);
avahi_helper = AvahiInit(loop, serviceName, listen_port);
#endif
#ifdef HAVE_BONJOUR
@ -100,14 +107,11 @@ ZeroconfInit(const ConfigData &config, [[maybe_unused]] EventLoop &loop)
void
ZeroconfDeinit() noexcept
{
#ifdef HAVE_AVAHI
avahi_helper.reset();
#endif
#ifdef HAVE_BONJOUR
bonjour_helper.reset();
#endif
if (!zeroconfEnabled)
return;
#ifdef HAVE_AVAHI
AvahiDeinit();
#endif /* HAVE_AVAHI */
}

View File

@ -17,29 +17,23 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "Init.hxx"
#include "../Internal.hxx"
#include "Helper.hxx"
#include "Client.hxx"
#include "ConnectionListener.hxx"
#include "ErrorHandler.hxx"
#include "Publisher.hxx"
#include "Service.hxx"
#include "../Internal.hxx"
#include "util/RuntimeError.hxx"
#include "Log.hxx"
#include <avahi-common/domain.h>
class AvahiGlue final : Avahi::ErrorHandler {
class SharedAvahiClient : public Avahi::ErrorHandler {
public:
Avahi::Client client;
Avahi::Publisher publisher;
AvahiGlue(EventLoop &event_loop,
const char *name, std::forward_list<Avahi::Service> services)
:client(event_loop, *this),
publisher(client, name, std::move(services), *this)
{
}
SharedAvahiClient(EventLoop &event_loop)
:client(event_loop, *this) {}
/* virtual methods from class Avahi::ErrorHandler */
bool OnAvahiError(std::exception_ptr e) noexcept override {
@ -48,24 +42,38 @@ public:
}
};
static AvahiGlue *avahi_glue;
static std::weak_ptr<SharedAvahiClient> shared_avahi_client;
void
AvahiInit(EventLoop &loop, const char *serviceName, unsigned port)
inline
AvahiHelper::AvahiHelper(std::shared_ptr<SharedAvahiClient> _client,
std::unique_ptr<Avahi::Publisher> _publisher)
:client(std::move(_client)),
publisher(std::move(_publisher)) {}
AvahiHelper::~AvahiHelper() noexcept = default;
std::unique_ptr<AvahiHelper>
AvahiInit(EventLoop &event_loop, const char *service_name, unsigned port)
{
if (!avahi_is_valid_service_name(serviceName))
throw FormatRuntimeError("Invalid zeroconf_name \"%s\"", serviceName);
if (!avahi_is_valid_service_name(service_name))
throw FormatRuntimeError("Invalid zeroconf_name \"%s\"",
service_name);
auto client = shared_avahi_client.lock();
if (!client)
shared_avahi_client = client =
std::make_shared<SharedAvahiClient>(event_loop);
std::forward_list<Avahi::Service> services;
services.emplace_front(AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC,
SERVICE_TYPE, port);
avahi_glue = new AvahiGlue(loop, serviceName, std::move(services));
}
auto publisher = std::make_unique<Avahi::Publisher>(client->client,
service_name,
std::move(services),
*client);
void
AvahiDeinit()
{
delete avahi_glue;
return std::make_unique<AvahiHelper>(std::move(client),
std::move(publisher));
}

View File

@ -17,15 +17,27 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ZEROCONF_AVAHI_HXX
#define MPD_ZEROCONF_AVAHI_HXX
#ifndef MPD_ZEROCONF_AVAHI_HELPER_HXX
#define MPD_ZEROCONF_AVAHI_HELPER_HXX
#include <memory>
class EventLoop;
namespace Avahi { class Publisher; }
void
AvahiInit(EventLoop &loop, const char *service_name, unsigned port);
class SharedAvahiClient;
void
AvahiDeinit();
class AvahiHelper final {
std::shared_ptr<SharedAvahiClient> client;
std::unique_ptr<Avahi::Publisher> publisher;
public:
AvahiHelper(std::shared_ptr<SharedAvahiClient> _client,
std::unique_ptr<Avahi::Publisher> _publisher);
~AvahiHelper() noexcept;
};
std::unique_ptr<AvahiHelper>
AvahiInit(EventLoop &event_loop, const char *service_name, unsigned port);
#endif

View File

@ -6,7 +6,7 @@ endif
avahi = static_library(
'avahi',
'Init.cxx',
'Helper.cxx',
'Client.cxx',
'Error.cxx',
'Poll.cxx',

View File

@ -19,7 +19,7 @@
#include "event/Loop.hxx"
#include "ShutdownHandler.hxx"
#include "zeroconf/avahi/Init.hxx"
#include "zeroconf/avahi/Helper.hxx"
#include <stdlib.h>
@ -29,11 +29,9 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
EventLoop event_loop;
const ShutdownHandler shutdown_handler(event_loop);
AvahiInit(event_loop, "test", 1234);
const auto helper = AvahiInit(event_loop, "test", 1234);
event_loop.Run();
AvahiDeinit();
return EXIT_SUCCESS;
}