![JAR search and dependency download from the Maven repository](/logo.png)
com.oracle.coherence.common.internal.net.InterruptibleChannels Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.oracle.coherence.common.internal.net;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.channels.spi.AbstractInterruptibleChannel;
/**
* Set of InterruptibleChannels related helper methods.
*
* @author mf 2013.11.04
*/
public final class InterruptibleChannels
{
/**
* Attempt to change a channel's interruptibility.
*
* Note: this feature is deprecated as it no longer with Java 9.
*
* @param chan the channel
* @param fInterruptible true if interrupts are to be supported; false otherwise
*
* @return true iff the channel was successfully updated
*
* @deprecated
*/
public static boolean setInterruptible(AbstractInterruptibleChannel chan, boolean fInterruptible)
{
// This is a "work-around for"
// JDK-6908931 : (so) Thread.interrupt impact on thread doing non-blocking I/O operation is not clear
if (s_fieldInterruptor == null || (!fInterruptible && s_interruptibleNoOp == null))
{
return false;
}
try
{
while (chan instanceof WrapperSocketChannel) // special awareness of wrapper channels
{
chan = ((WrapperSocketChannel) chan).f_delegate;
}
s_fieldInterruptor.set(chan, fInterruptible
? null
: s_interruptibleNoOp);
return true;
}
catch (Throwable e)
{
return false;
}
}
// ----- inner class: InterruptibleFetcher ------------------------------
/**
* Helper hack to fetch an implementation of sun.nio.ch.Interruptible
*/
private static class InterruptibleFetcher
extends AbstractInterruptibleChannel
{
/**
* Retrieve the internal interruptible and close the channel.
*
* @return the interruptible
*/
Object fetch()
{
try
{
begin(); // initializes the interruptor field
return s_fieldInterruptor.get(this);
}
catch (Throwable e) {}
finally
{
try
{
end(true);
close();
}
catch (Throwable e) {}
}
return null;
}
@Override
protected void implCloseChannel()
throws IOException
{
}
}
// ----- constants ------------------------------------------------------
/**
* Field for accessing an AbstractInterruptibleChannel's private interruptor.
*/
private static final Field s_fieldInterruptor;
/**
* An InterruptibleNoOp, obtained from a pre-closed channel.
*/
private static final Object s_interruptibleNoOp;
static
{
Field field = null;
try
{
if (System.getProperty("java.vm.specification.version").startsWith("1."))
{
Field fieldTmp = AbstractInterruptibleChannel.class.getDeclaredField("interruptor");
fieldTmp.setAccessible(true);
field = fieldTmp;
}
// else; we're on at least 9, it is inaccessable unless --permit-illegal-access is specified and
// that generates warnings. The primary usecase for this functionality is TMB, and thankfully TMB will do
// reconnects on unexpected closes, so we simply drop this feature
}
catch (Throwable e) {}
s_fieldInterruptor = field;
s_interruptibleNoOp = field == null ? null : new InterruptibleFetcher().fetch();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy