[#2013] Fix a race which could happen to have the worker Thread interrupted during close(...) when using OIO

This commit is contained in:
Norman Maurer 2013-11-25 18:43:18 +01:00
parent 4a5c21b2e1
commit b8de307b0d
2 changed files with 36 additions and 12 deletions

View File

@ -87,9 +87,14 @@ class OioDatagramWorker implements Runnable {
packet.getSocketAddress());
}
// Setting the workerThread to null will prevent any channel
// operations from interrupting this thread from now on.
channel.workerThread = null;
synchronized (channel.interestOpsLock) {
// Setting the workerThread to null will prevent any channel
// operations from interrupting this thread from now on.
//
// Do this while holding the lock to not race with close(...) or
// setInterestOps(...)
channel.workerThread = null;
}
// Clean up.
close(channel, succeededFuture(channel));
@ -202,9 +207,16 @@ class OioDatagramWorker implements Runnable {
if (connected) {
// Notify the worker so it stops reading.
Thread currentThread = Thread.currentThread();
Thread workerThread = channel.workerThread;
if (workerThread != null && currentThread != workerThread) {
workerThread.interrupt();
synchronized (channel.interestOpsLock) {
// We need to do this while hold the lock as otherwise
// we may race and so interrupt the workerThread even
// if we are in the workerThread now.
// This can happen if run() set channel.workerThread to null
// between workerThread != null and currentThread!= workerThread
Thread workerThread = channel.workerThread;
if (workerThread != null && currentThread != workerThread) {
workerThread.interrupt();
}
}
fireChannelDisconnected(channel);
}

View File

@ -102,9 +102,14 @@ class OioWorker implements Runnable {
channel.getConfig().getBufferFactory().getBuffer(buf, 0, readBytes));
}
// Setting the workerThread to null will prevent any channel
// operations from interrupting this thread from now on.
channel.workerThread = null;
synchronized (channel.interestOpsLock) {
// Setting the workerThread to null will prevent any channel
// operations from interrupting this thread from now on.
//
// Do this while holding the lock to not race with close(...) or
// setInterestOps(...)
channel.workerThread = null;
}
// Clean up.
close(channel, succeededFuture(channel));
@ -222,9 +227,16 @@ class OioWorker implements Runnable {
if (connected) {
// Notify the worker so it stops reading.
Thread currentThread = Thread.currentThread();
Thread workerThread = channel.workerThread;
if (workerThread != null && currentThread != workerThread) {
workerThread.interrupt();
synchronized (channel.interestOpsLock) {
// We need to do this while hold the lock as otherwise
// we may race and so interrupt the workerThread even
// if we are in the workerThread now.
// This can happen if run() set channel.workerThread to null
// between workerThread != null and currentThread!= workerThread
Thread workerThread = channel.workerThread;
if (workerThread != null && currentThread != workerThread) {
workerThread.interrupt();
}
}
fireChannelDisconnected(channel);
}