Commit 3ddc178b authored by Daniel Sonck's avatar Daniel Sonck
Browse files

[THFMA-28] Fix crash due to resolveHost executed on UI thread

- Perform delayed resolveHost when host information is necessary
parent 1764e70d
......@@ -24,7 +24,7 @@ import fm.touhou.touhoufm.utils.*
import java.io.IOException
import java.net.*
class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener: MetaListener, private val progressListener: ProgressListener, private var streamHost: String, private var streamPort: Int) : Thread("RtpThread") {
class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener: MetaListener, private val progressListener: ProgressListener, private var mStreamHost: String, private var mStreamPort: Int) : Thread("RtpThread") {
private var mLastSeqNum = 0
private var mDuration = 0
......@@ -56,9 +56,8 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
override fun run() {
try {
val udpImpl = UdpImpl(DatagramSocket(), streamPort)
val udpImpl = UdpImpl(DatagramSocket(), mStreamHost, mStreamPort)
mUdpImpl = udpImpl
udpImpl.resolveHost(streamHost)
udpImpl.initUdpConn()
udpImpl.play()
udpImpl.clrUdpConn()
......@@ -72,21 +71,38 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
}
fun setStreamHost(streamHost: String) {
this.streamHost = streamHost
mUdpImpl?.resolveHost(this.streamHost)
mStreamHost = streamHost
mUdpImpl?.setStreamHost(mStreamHost)
}
fun setStreamPort(streamPort: Int) {
this.streamPort = streamPort
mUdpImpl?.setStreamPort(streamPort)
mStreamPort = streamPort
mUdpImpl?.setStreamPort(mStreamPort)
}
inner class UdpImpl(private val mRecvSocket: DatagramSocket, private var mStreamPort: Int) {
private var address: InetAddress? = null
private val addressLock = Object()
inner class UdpImpl(private val mRecvSocket: DatagramSocket, private var mStreamHost: String, private var mStreamPort: Int) {
private var mAddressCache: InetAddress? = null
private val mAddressLock = Object()
val pcmFrames = ShortArray(BUF_SIZE)
val mPcmFrames = ShortArray(BUF_SIZE)
private val address: InetAddress
get() {
synchronized(mAddressLock) {
mAddressCache.let {
if (it != null)
return it
else {
val address = resolveHost(mStreamHost)
mAddressCache = address
return address
}
}
}
}
private val port: Int
get() = synchronized(mStreamPort) { mStreamPort }
private val packetHandler = object : PacketReceiver {
......@@ -110,10 +126,10 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
mLastSeqNum = sequenceNumber
// Decode the opus data into pcm frames
val samps = mOpusDecoder?.decode(opus, pcmFrames) ?: 0
val samps = mOpusDecoder?.decode(opus, mPcmFrames) ?: 0
// Write the audio data to the buffer
if (mRingBuffer.write(pcmFrames, samps * 2) < 0) {
if (mRingBuffer.write(mPcmFrames, samps * 2) < 0) {
// If the write returns -1, this means the buffer is aborted and we should stop
interrupt()
}
......@@ -134,7 +150,7 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
try {
// send mic off
val msg = "Bye"
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, synchronized(addressLock) { address }, synchronized(mStreamPort) { mStreamPort })
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, address, port)
mRecvSocket.send(sendPacket)
} catch (e: IOException) {
Log.e(TAG, "Failed to clr udp conn", e)
......@@ -143,29 +159,24 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
}
@Throws(UnknownHostException::class)
fun resolveHost(streamHost: String) {
private fun resolveHost(streamHost: String): InetAddress {
var count = 8
synchronized(addressLock) {
address = null
while (address == null) {
try {
address = InetAddress.getByName(streamHost)
} catch (e: UnknownHostException) {
if (count < 0) {
address = null
throw e
} else {
try {
sleep(10000)
} catch (e1: InterruptedException) {
interrupt()
}
while (true) {
try {
return InetAddress.getByName(streamHost)
} catch (e: UnknownHostException) {
if (count < 0) {
throw e
} else {
try {
sleep(10000)
} catch (e1: InterruptedException) {
interrupt()
}
}
count--
}
count--
}
}
......@@ -175,7 +186,7 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
val msg = "Hello"
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, synchronized(addressLock) { address }, synchronized(mStreamPort) { mStreamPort })
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, address, port)
var retry = true
......@@ -208,7 +219,7 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
@Throws(UnknownHostException::class)
internal fun initUdpConn() {
val msg = "Hello"
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, synchronized(addressLock) { address }, synchronized(mStreamPort) { mStreamPort })
val sendPacket = DatagramPacket(msg.toByteArray(), msg.length, address, port)
try {
mRecvSocket.send(sendPacket)
......@@ -281,6 +292,13 @@ class RtpReceiver(private val mRingBuffer: RingBuffer, private val metaListener:
}
}
fun setStreamHost(streamHost: String) {
synchronized(mAddressLock) {
mStreamHost = streamHost
mAddressCache = null
}
}
}
private fun shutDown() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment