blob: 6a17ea0876adccb74917da9a5624ac0659521b01 [file] [log] [blame]
Austin Schuh75263e32022-02-22 18:05:32 -08001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#include "AvahiClient.h"
6
7#include <wpi/mutex.h>
8
9#include <thread>
10
11#include "dlfcn.h"
12
13using namespace wpi;
14
15#define AvahiFunctionLoad(snake_name) \
16 do { \
17 snake_name = \
18 reinterpret_cast<snake_name##_func>(dlsym(lib, "avahi_" #snake_name)); \
19 if (!snake_name) { \
20 return; \
21 } \
22 } while (false)
23
24AvahiFunctionTable::AvahiFunctionTable() {
25 void* lib = dlopen("libavahi-common.so.3", RTLD_LAZY);
26
27 valid = false;
28
29 if (lib == nullptr) {
30 return;
31 }
32
33 AvahiFunctionLoad(threaded_poll_new);
34 AvahiFunctionLoad(threaded_poll_free);
35 AvahiFunctionLoad(threaded_poll_get);
36 AvahiFunctionLoad(threaded_poll_start);
37 AvahiFunctionLoad(threaded_poll_stop);
38 AvahiFunctionLoad(threaded_poll_lock);
39 AvahiFunctionLoad(threaded_poll_unlock);
40 AvahiFunctionLoad(string_list_new_from_array);
41 AvahiFunctionLoad(string_list_free);
42 AvahiFunctionLoad(unescape_label);
43 AvahiFunctionLoad(alternative_service_name);
44 AvahiFunctionLoad(free);
45
46 lib = dlopen("libavahi-client.so.3", RTLD_LAZY);
47
48 if (lib == nullptr) {
49 return;
50 }
51
52 AvahiFunctionLoad(client_new);
53 AvahiFunctionLoad(client_free);
54 AvahiFunctionLoad(service_browser_new);
55 AvahiFunctionLoad(service_browser_get_client);
56 AvahiFunctionLoad(service_browser_free);
57 AvahiFunctionLoad(service_resolver_new);
58 AvahiFunctionLoad(service_resolver_free);
59 AvahiFunctionLoad(entry_group_new);
60 AvahiFunctionLoad(entry_group_free);
61 AvahiFunctionLoad(entry_group_add_service_strlst);
62 AvahiFunctionLoad(entry_group_reset);
63 AvahiFunctionLoad(entry_group_is_empty);
64 AvahiFunctionLoad(entry_group_commit);
65 AvahiFunctionLoad(entry_group_get_client);
66
67 valid = true;
68}
69
70AvahiFunctionTable& AvahiFunctionTable::Get() {
71 static AvahiFunctionTable table;
72 return table;
73}
74
75static wpi::mutex ThreadLoopLock;
76static std::weak_ptr<AvahiThread> ThreadLoop;
77
78std::shared_ptr<AvahiThread> AvahiThread::Get() {
79 std::scoped_lock lock{ThreadLoopLock};
80 auto locked = ThreadLoop.lock();
81 if (!locked) {
82 locked = std::make_unique<AvahiThread>(private_init{});
83 ThreadLoop = locked;
84 }
85 return locked;
86}
87
88AvahiThread::AvahiThread(const private_init&) {
89 if (!table.IsValid()) {
90 return;
91 }
92
93 threadedPoll = table.threaded_poll_new();
94 table.threaded_poll_start(threadedPoll);
95}
96
97AvahiThread::~AvahiThread() noexcept {
98 if (!table.IsValid()) {
99 return;
100 }
101
102 if (threadedPoll) {
103 table.threaded_poll_stop(threadedPoll);
104 table.threaded_poll_free(threadedPoll);
105 }
106}
107
108void AvahiThread::lock() {
109 table.threaded_poll_lock(threadedPoll);
110}
111
112void AvahiThread::unlock() {
113 table.threaded_poll_unlock(threadedPoll);
114}
115
116const AvahiPoll* AvahiThread::GetPoll() const {
117 return table.threaded_poll_get(threadedPoll);
118}