diff --git a/src/main/kotlin/net/eksb/obsdc/DBus.kt b/src/main/kotlin/net/eksb/obsdc/DBus.kt index 079713c..1a7e58c 100644 --- a/src/main/kotlin/net/eksb/obsdc/DBus.kt +++ b/src/main/kotlin/net/eksb/obsdc/DBus.kt @@ -3,6 +3,7 @@ package net.eksb.obsdc import org.freedesktop.dbus.annotations.DBusInterfaceName import org.freedesktop.dbus.connections.impl.DBusConnection import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder +import org.freedesktop.dbus.exceptions.DBusException import org.freedesktop.dbus.interfaces.DBusInterface import org.freedesktop.dbus.interfaces.DBusSigHandler import org.freedesktop.dbus.messages.DBusSignal @@ -26,23 +27,32 @@ class DBus(private val opRunner:OpRunner): AutoCloseable { val dbus = DBusConnectionBuilder.forSessionBus().build() init { - // These lines are not necessary to handle signals, but are necessary to register methods. - dbus.requestBusName("net.eksb.obsdc") - dbus.exportObject("/", ObsdcDBusInterfaceImpl()) + // These lines are not necessary to handle signals, but are necessary to register methods. + try { + dbus.requestBusName(BUS_NAME) + } catch (e:DBusException) { + error("Error requesting bus. Already running?") + } + dbus.exportObject("/", ObsdcDBusInterfaceImpl()) - dbus.addSigHandler { signal -> - log.debug("signal: ${signal.op}") - val op = Op.valueOf(signal.op) - log.debug("op: ${op}") - opRunner.run(op) - } + dbus.addSigHandler { signal -> + log.debug("signal: ${signal.op}") + val op = Op.valueOf(signal.op) + log.debug("op: ${op}") + opRunner.run(op) + } + log.debug("DBUS initialized") } override fun close() { + dbus.releaseBusName(BUS_NAME) dbus.close() } - private val log = LoggerFactory.getLogger(DBus::class.java) + companion object { + private const val BUS_NAME = "net.eksb.obsdc" + private val log = LoggerFactory.getLogger(DBus::class.java) + } } inline fun DBusConnection.addSigHandler(handler: DBusSigHandler) { diff --git a/src/main/kotlin/net/eksb/obsdc/Main.kt b/src/main/kotlin/net/eksb/obsdc/Main.kt index 6364f94..fa47773 100644 --- a/src/main/kotlin/net/eksb/obsdc/Main.kt +++ b/src/main/kotlin/net/eksb/obsdc/Main.kt @@ -1,18 +1,26 @@ package net.eksb.obsdc +import org.slf4j.LoggerFactory + object Main { @JvmStatic fun main(args: Array) { - val config = CONFIG_FILE.properties() - Obs( - host = config.getProperty("host") ?: "localhost", - port = config.getProperty("port")?.toInt() ?: 4455, - password = config.getProperty("password") ?: error("config missing \"password\""), - connectionTimeout = config.getProperty("connectionTimeout")?.toInt() ?: 5 - ).use { obs -> - DBus(OpRunner(obs)).use { dbus -> - waitForShutdown() + try { + val config = CONFIG_FILE.properties() + Obs( + host = config.getProperty("host") ?: "localhost", + port = config.getProperty("port")?.toInt() ?: 4455, + password = config.getProperty("password") ?: error("config missing \"password\""), + connectionTimeout = config.getProperty("connectionTimeout")?.toInt() ?: 5 + ).use { obs -> + DBus(OpRunner(obs)).use { dbus -> + waitForShutdown() + } } + } catch (e:Exception) { + log.error(e.message, e) } } + + private val log = LoggerFactory.getLogger(Main::class.java) } \ No newline at end of file diff --git a/src/main/kotlin/net/eksb/obsdc/Obs.kt b/src/main/kotlin/net/eksb/obsdc/Obs.kt index 2a3b503..76851a9 100644 --- a/src/main/kotlin/net/eksb/obsdc/Obs.kt +++ b/src/main/kotlin/net/eksb/obsdc/Obs.kt @@ -48,7 +48,7 @@ class Obs( .host(host) .port(port) .password(password) - .autoConnect(true) + .autoConnect(false) .connectionTimeout(connectionTimeout) .lifecycle() .onReady(::onReady) @@ -69,6 +69,10 @@ class Obs( addShutdownHook { close() } + // connect() blocks until OBS is up, so fork it. + thread(name="obs-init-connect", isDaemon=true, start=true) { + controller.connect() + } } private fun onClose(e:WebSocketCloseCode) { @@ -112,22 +116,24 @@ class Obs( /** * Thread that runs submitted requests from [q] when [ready]. */ - private val opThread = thread(name="obs-op", isDaemon=true, start=true) { + private val opThread = thread(name="obs-op", isDaemon=false, start=true) { while(!closed.get()) { - val req = q.take() + val req = try { + q.take() + } catch (e:InterruptedException) { + log.debug("interrupted taking req") + continue + } log.debug("got req: ${req}, wait for ready") - ready.enter { - log.debug("ready") - if (!req.expired()) { - try { - req.block.invoke(controller) - } catch (e:InterruptedException) { - log.debug("interrupted") - throw e - } catch (e:Exception) { - log.error("req ${req} failed", e ) + try { + ready.enter { + log.debug("ready") + if (!req.expired()) { + req.block.invoke(controller) } } + } catch (e:Exception) { + log.error("req ${req} failed", e ) } } log.debug("done") @@ -147,7 +153,6 @@ class Obs( } override fun close() { - log.debug("close") closed.set(true) opThread.interrupt() controller.disconnect()