Skip to content

Commit 697e345

Browse files
committed
avahi: pass proxy along with interface
This way we are not relying on private member of interface to get access to the bus.
1 parent 6322e29 commit 697e345

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/dnssd/avahi.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ interface ServiceBrowser extends dbus.ClientInterface {
4848
// on(event: 'CacheExhausted', listener: () => void): this;
4949
}
5050

51-
let cachedServer: Server | undefined;
51+
type ServerObject = {
52+
proxy: dbus.ProxyObject;
53+
iface: Server;
54+
};
5255

53-
async function getServer(): Promise<Server> {
56+
let cachedServer: ServerObject | undefined;
57+
58+
async function getServer(): Promise<ServerObject> {
5459
if (cachedServer === undefined) {
5560
const bus = dbus.systemBus();
5661
// dbus-next will queue messages and wait forever for a connection
@@ -66,9 +71,9 @@ async function getServer(): Promise<Server> {
6671
});
6772
});
6873
const proxy = await bus.getProxyObject('org.freedesktop.Avahi', '/');
69-
const server = proxy.getInterface<Server>('org.freedesktop.Avahi.Server');
70-
const version = await server.GetAPIVersion();
71-
cachedServer = server;
74+
const iface = proxy.getInterface<Server>('org.freedesktop.Avahi.Server');
75+
const version = await iface.GetAPIVersion();
76+
cachedServer = { proxy, iface };
7277
}
7378

7479
return cachedServer;
@@ -82,7 +87,7 @@ export async function getInstance(): Promise<dnssd.Client> {
8287
class AvahiClient implements dnssd.Client {
8388
private destroyOps = new Array<() => void>();
8489

85-
constructor(readonly server: Server) {
90+
constructor(public readonly server: ServerObject) {
8691
}
8792

8893
public createBrowser(options: dnssd.BrowseOptions): Promise<dnssd.Browser> {
@@ -134,18 +139,24 @@ class AvahiBrowser extends events.EventEmitter implements dnssd.Browser {
134139

135140
constructor(private readonly client: AvahiClient, private options: dnssd.BrowseOptions) {
136141
super();
137-
this.bus = (client.server as any).$object.bus;
142+
// Due to race condition: https://github.com/lathiat/avahi/issues/9
143+
// we have to add signal listeners now before creating browser objects
144+
// otherwise we miss signals.
145+
this.bus = client.server.proxy.bus;
138146
(this.bus as any).on('message', (msg: dbus.Message) => {
139147
if (msg.type !== dbus.MessageType.SIGNAL) {
140148
return;
141149
}
142150
if (msg.interface !== 'org.freedesktop.Avahi.ServiceBrowser') {
143151
return;
144152
}
153+
// TODO: should also check msg.path, but we can receive messages
154+
// before ServiceBrowserNew() returns when we don't know the path
155+
// yet.
145156
switch (msg.member) {
146157
case 'ItemNew': {
147158
const [iface, protocol, name, type, domain, flags] = msg.body;
148-
client.server.ResolveService(iface, protocol, name, type, domain, protocol, 0).then(
159+
client.server.iface.ResolveService(iface, protocol, name, type, domain, protocol, 0).then(
149160
([iface, protocol, name, type, domain, host, aprotocol, addr, port, txt, flags]) => {
150161
const service = new AvahiService(iface, protocol, name, type, domain, host, aprotocol, addr, port, txt, flags);
151162
this.services.push(service);
@@ -183,7 +194,7 @@ class AvahiBrowser extends events.EventEmitter implements dnssd.Browser {
183194
public async start(): Promise<void> {
184195
const proto = this.options.ipv === 'IPv6' ? PROTO_INET6 : PROTO_INET;
185196
const type = `_${this.options.service}._${this.options.transport || 'tcp'}`;
186-
const objPath = await this.client.server.ServiceBrowserNew(IF_UNSPEC, proto, type, '', 0);
197+
const objPath = await this.client.server.iface.ServiceBrowserNew(IF_UNSPEC, proto, type, '', 0);
187198
const proxy = await this.bus.getProxyObject('org.freedesktop.Avahi', objPath);
188199
this.browser = proxy.getInterface<ServiceBrowser>('org.freedesktop.Avahi.ServiceBrowser');
189200
}

0 commit comments

Comments
 (0)