-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from xxDark/master
Add fallback path for locked-up environments
- Loading branch information
Showing
5 changed files
with
212 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package software.coley.llzip.util; | ||
|
||
import sun.misc.Unsafe; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.nio.ByteBuffer; | ||
|
||
/** | ||
* Utility to invoke cleaners in a {@link ByteBuffer}. | ||
* | ||
* @author xDark | ||
*/ | ||
public final class CleanerUtil { | ||
|
||
private static final Method INVOKE_CLEANER; | ||
private static final Method GET_CLEANER; | ||
private static final boolean SUPPORTED; | ||
|
||
private CleanerUtil() { | ||
} | ||
|
||
/** | ||
* Attempts to clean direct buffer. | ||
* | ||
* @param buffer | ||
* Buffer to clean. | ||
* | ||
* @throws IllegalStateException | ||
* If buffer is not direct, slice or duplicate, or | ||
* cleaner failed to invoke. | ||
*/ | ||
public static void invokeCleaner(ByteBuffer buffer) { | ||
if (!buffer.isDirect()) { | ||
throw new IllegalStateException("buffer is not direct"); | ||
} | ||
if (!SUPPORTED) { | ||
return; | ||
} | ||
Method getCleaner = GET_CLEANER; | ||
Method invokeCleaner = INVOKE_CLEANER; | ||
try { | ||
if (getCleaner != null) { | ||
Object cleaner = getCleaner.invoke(buffer); | ||
if (cleaner == null) { | ||
throw new IllegalStateException("slice or duplicate"); | ||
} | ||
invokeCleaner.invoke(cleaner); | ||
} else { | ||
invokeCleaner.invoke(UnsafeUtil.get(), buffer); | ||
} | ||
} catch(InvocationTargetException ex) { | ||
throw new IllegalStateException("Failed to invoke clean method", ex.getTargetException()); | ||
} catch(IllegalAccessException ex) { | ||
throw new IllegalStateException("cleaner became inaccessible", ex); | ||
} | ||
} | ||
|
||
static { | ||
boolean supported = false; | ||
Method invokeCleaner; | ||
Method getCleaner = null; | ||
try { | ||
invokeCleaner = Unsafe.class.getDeclaredMethod("invokeCleaner", ByteBuffer.class); | ||
invokeCleaner.setAccessible(true); | ||
ByteBuffer tmp = ByteBuffer.allocateDirect(1); | ||
invokeCleaner.invoke(UnsafeUtil.get(), tmp); | ||
supported = true; | ||
} catch(NoSuchMethodException ignored) { | ||
supported = true; | ||
ByteBuffer tmp = ByteBuffer.allocateDirect(1); | ||
try { | ||
Class<?> directBuffer = Class.forName("sun.nio.ch.DirectBuffer"); | ||
getCleaner = directBuffer.getDeclaredMethod("cleaner"); | ||
invokeCleaner = getCleaner.getReturnType().getDeclaredMethod("clean"); | ||
invokeCleaner.setAccessible(true); | ||
getCleaner.setAccessible(true); | ||
invokeCleaner.invoke(getCleaner.invoke(tmp)); | ||
} catch(Exception ignored1) { | ||
invokeCleaner = null; | ||
getCleaner = null; | ||
supported = false; | ||
} | ||
} catch(Exception ex) { | ||
invokeCleaner = null; | ||
} | ||
INVOKE_CLEANER = invokeCleaner; | ||
GET_CLEANER = getCleaner; | ||
SUPPORTED = supported; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.