Added lock downgrades and fixed unlocking ordering
This commit is contained in:
parent
d5095be95d
commit
63a182afd7
1 changed files with 54 additions and 48 deletions
|
|
@ -74,22 +74,24 @@ trait NettyRemoteClientModule extends RemoteClientModule with NettyRemoteShared
|
||||||
|
|
||||||
val key = makeKey(address)
|
val key = makeKey(address)
|
||||||
lock.readLock.lock
|
lock.readLock.lock
|
||||||
remoteClients.get(key) match {
|
try {
|
||||||
case Some(client) => try { client } finally { lock.readLock.unlock }
|
remoteClients.get(key) match {
|
||||||
case None =>
|
case Some(client) => client
|
||||||
lock.readLock.unlock
|
case None =>
|
||||||
lock.writeLock.lock //Lock upgrade, not supported natively
|
lock.readLock.unlock
|
||||||
try {
|
lock.writeLock.lock //Lock upgrade, not supported natively
|
||||||
remoteClients.get(key) match { //Recheck for addition, race between upgrades
|
try {
|
||||||
case Some(client) => client //If already populated by other writer
|
remoteClients.get(key) match { //Recheck for addition, race between upgrades
|
||||||
case None => //Populate map
|
case Some(client) => client //If already populated by other writer
|
||||||
val client = new ActiveRemoteClient(this, address, loader, self.notifyListeners _)
|
case None => //Populate map
|
||||||
client.connect()
|
val client = new ActiveRemoteClient(this, address, loader, self.notifyListeners _)
|
||||||
remoteClients += key -> client
|
client.connect()
|
||||||
client
|
remoteClients += key -> client
|
||||||
}
|
client
|
||||||
} finally { lock.writeLock.unlock }
|
}
|
||||||
}
|
} finally { lock.readLock.lock; lock.writeLock.unlock } //downgrade
|
||||||
|
}
|
||||||
|
} finally { lock.readLock.unlock }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,22 +101,24 @@ trait NettyRemoteClientModule extends RemoteClientModule with NettyRemoteShared
|
||||||
val address = channel.getRemoteAddress.asInstanceOf[InetSocketAddress]
|
val address = channel.getRemoteAddress.asInstanceOf[InetSocketAddress]
|
||||||
val key = makeKey(address)
|
val key = makeKey(address)
|
||||||
lock.readLock.lock
|
lock.readLock.lock
|
||||||
remoteClients.get(key) match {
|
try {
|
||||||
case Some(client) => try { false } finally { lock.readLock.unlock }
|
remoteClients.get(key) match {
|
||||||
case None =>
|
case Some(client) => false
|
||||||
lock.readLock.unlock
|
case None =>
|
||||||
lock.writeLock.lock //Lock upgrade, not supported natively
|
lock.readLock.unlock
|
||||||
try {
|
lock.writeLock.lock //Lock upgrade, not supported natively
|
||||||
remoteClients.get(key) match {
|
try {
|
||||||
case Some(client) => false
|
remoteClients.get(key) match {
|
||||||
case None =>
|
case Some(client) => false
|
||||||
val client = new PassiveRemoteClient(this, address, channel, self.notifyListeners _ )
|
case None =>
|
||||||
client.connect()
|
val client = new PassiveRemoteClient(this, address, channel, self.notifyListeners _ )
|
||||||
remoteClients.put(key, client)
|
client.connect()
|
||||||
true
|
remoteClients.put(key, client)
|
||||||
}
|
true
|
||||||
} finally { lock.writeLock.unlock }
|
}
|
||||||
}
|
} finally { lock.readLock.lock; lock.writeLock.unlock } //downgrade
|
||||||
|
}
|
||||||
|
} finally { lock.readLock.unlock }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -124,22 +128,24 @@ trait NettyRemoteClientModule extends RemoteClientModule with NettyRemoteShared
|
||||||
val address = channel.getRemoteAddress.asInstanceOf[InetSocketAddress]
|
val address = channel.getRemoteAddress.asInstanceOf[InetSocketAddress]
|
||||||
val key = makeKey(address)
|
val key = makeKey(address)
|
||||||
lock.readLock.lock
|
lock.readLock.lock
|
||||||
remoteClients.get(key) match {
|
try {
|
||||||
case Some(client: PassiveRemoteClient) =>
|
remoteClients.get(key) match {
|
||||||
lock.readLock.unlock
|
case Some(client: PassiveRemoteClient) =>
|
||||||
lock.writeLock.lock //Lock upgrade, not supported natively
|
lock.readLock.unlock
|
||||||
try {
|
lock.writeLock.lock //Lock upgrade, not supported natively
|
||||||
remoteClients.get(key) match {
|
try {
|
||||||
case Some(client: ActiveRemoteClient) => false
|
remoteClients.get(key) match {
|
||||||
case None => false
|
case Some(client: ActiveRemoteClient) => false
|
||||||
case Some(client: PassiveRemoteClient) =>
|
case None => false
|
||||||
remoteClients.remove(key)
|
case Some(client: PassiveRemoteClient) =>
|
||||||
true
|
remoteClients.remove(key)
|
||||||
}
|
true
|
||||||
} finally { lock.writeLock.unlock }
|
}
|
||||||
//Otherwise, unlock the readlock and return false
|
} finally { lock.readLock.lock; lock.writeLock.unlock } //downgrade
|
||||||
case _ => try { false } finally { lock.readLock.unlock }
|
//Otherwise, unlock the readlock and return false
|
||||||
}
|
case _ => false
|
||||||
|
}
|
||||||
|
} finally { lock.readLock.unlock }
|
||||||
}
|
}
|
||||||
|
|
||||||
private def makeKey(a: InetSocketAddress): String = a match {
|
private def makeKey(a: InetSocketAddress): String = a match {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue