Remove ancient unsafe native code.

All Javas have reasonably fine grained Thread.sleep these days, and we no
longer need to set our pid or gid or temporarily disable GC.
This commit is contained in:
Michael Bayne
2025-02-10 10:15:32 -08:00
parent fbe72595a4
commit f1441a8be6
16 changed files with 6 additions and 718 deletions
@@ -37,8 +37,6 @@ import com.samskivert.util.StringUtil;
import com.samskivert.swing.RuntimeAdjust; import com.samskivert.swing.RuntimeAdjust;
import com.threerings.util.unsafe.Unsafe;
import com.threerings.media.timer.CalibratingTimer; import com.threerings.media.timer.CalibratingTimer;
import com.threerings.media.timer.MediaTimer; import com.threerings.media.timer.MediaTimer;
import com.threerings.media.timer.MillisTimer; import com.threerings.media.timer.MillisTimer;
@@ -640,7 +638,12 @@ public abstract class FrameManager
if (_perfDebug.getValue()) { if (_perfDebug.getValue()) {
start = _timer.getElapsedMicros(); start = _timer.getElapsedMicros();
} }
Unsafe.sleep(_sleepGranularity.getValue()); long millis = _sleepGranularity.getValue();
try {
Thread.sleep(millis);
} catch (InterruptedException ie) {
log.info("Thread.sleep(" + millis + ") interrupted.");
}
long woke = _timer.getElapsedMicros(); long woke = _timer.getElapsedMicros();
if (start > 0L) { if (start > 0L) {
@@ -1 +0,0 @@
Mac OS X
@@ -1,45 +0,0 @@
#
# $Id: Makefile 3332 2005-02-03 01:30:33Z mdb $
#
# Executable definitions
CC=gcc
RM=rm
CP=cp
MKDIR=mkdir
#
# Directory definitions
ROOT=../../../../../../../..
LIBRARIES_PATH=
OSINCDIR!=uname -s | tr 'A-Z' 'a-z'
INSTALL_PATH=${ROOT}/dist/lib/i386-FreeBSD
#
# Parameter and file definitions
INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/${OSINCDIR}
LIBRARIES=
TARGET=libunsafe.so
#
# Target definitions
all: ${TARGET}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling Unsafe.c"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo "Creating libunsafe.so"
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
clean:
-${RM} -f *.o ${TARGET}
@@ -1,117 +0,0 @@
/*
* $Id: com_threerings_util_unsafe_Unsafe.c 3653 2005-07-21 19:10:08Z mdb $
*/
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include <errno.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "com_threerings_util_unsafe_Unsafe.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
/** A sleep method that uses select(). This seems to have about 10ms
* granularity where nanosleep() has about 20ms. Sigh. */
static int select_sleep (int millisecs)
{
fd_set dummy;
struct timeval toWait;
FD_ZERO(&dummy);
toWait.tv_sec = millisecs / 1000;
toWait.tv_usec = (millisecs % 1000) * 1000;
return select(0, &dummy, NULL, NULL, &toWait);
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz)
{
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz)
{
jvmpi->DisableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSleep (
JNIEnv* env, jclass clazz, jint millis)
{
/* struct timespec tmspec; */
/* tmspec.tv_sec = millis/1000; */
/* tmspec.tv_nsec = (millis%1000)*1000000; */
/* if (nanosleep(&tmspec, NULL) < 0) { */
/* fprintf(stderr, "nanosleep() failed: %s\n", strerror(errno)); */
/* } */
if (select_sleep(millis) < 0) {
fprintf(stderr, "select_sleep() failed: %s\n", strerror(errno));
}
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSetuid (
JNIEnv* env, jclass clazz, jint uid)
{
if (setuid((uid_t)uid) != 0) {
fprintf(stderr, "setuid(%d) failed: %s\n", uid, strerror(errno));
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSetgid (
JNIEnv* env, jclass clazz, jint gid)
{
if (setgid((gid_t)gid) != 0) {
fprintf(stderr, "setgid(%d) failed: %s\n", gid, strerror(errno));
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSeteuid (
JNIEnv* env, jclass clzz, jint uid)
{
if (seteuid((uid_t)uid) != 0) {
fprintf(stderr, "seteuid(%d) failed: %s\n", uid, strerror(errno));
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetegid (
JNIEnv* env, jclass clazz, jint gid)
{
if (setegid((gid_t)gid) != 0) {
fprintf(stderr, "setegid(%d) failed: %s\n", gid, strerror(errno));
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -1,44 +0,0 @@
#
# $Id: Makefile 3331 2005-02-03 01:25:21Z mdb $
#
# Executable definitions
CC=gcc
RM=rm
CP=cp
MKDIR=mkdir
#
# Directory definitions
ROOT=../../../../../../../..
LIBRARIES_PATH=-L/usr/X11R6/lib
INSTALL_PATH=${ROOT}/dist/lib/i686-Linux
#
# Parameter and file definitions
INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
LIBRARIES=-lX11
TARGET=libunsafe.so
#
# Target definitions
all: ${TARGET}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
@echo Compiling Unsafe.c
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo Creating ${TARGET}
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
clean:
-${RM} -f *.o ${TARGET}
@@ -1 +0,0 @@
../FreeBSD/com_threerings_util_unsafe_Unsafe.c
@@ -1,45 +0,0 @@
#
# $Id: Makefile 3332 2005-02-03 01:30:33Z mdb $
#
# Executable definitions
CC=gcc
RM=rm
CP=cp
MKDIR=mkdir
#
# Directory definitions
ROOT=../../../../../../../..
LIBRARIES_PATH=
OSINCDIR!=uname -s | tr 'A-Z' 'a-z'
INSTALL_PATH=${ROOT}/dist/lib/`uname -m`-Darwin
#
# Parameter and file definitions
INCLUDES=-I.. -I/System/Library/Frameworks/JavaVM.framework/Headers
LIBRARIES=
TARGET=libunsafe.jnilib
#
# Target definitions
all: ${TARGET}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo "Creating $@"
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -dynamiclib
clean:
-${RM} -f *.o ${TARGET}
@@ -1 +0,0 @@
../FreeBSD/com_threerings_util_unsafe_Unsafe.c
@@ -1,209 +0,0 @@
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
// https://github.com/threerings/nenya
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.util.unsafe;
import com.samskivert.util.RunAnywhere;
import static com.threerings.NenyaLog.log;
/**
* A native library for doing unsafe things. Don't use this library. If
* you must ignore that warning, then be sure you use it sparingly and
* only in very well considered cases.
*/
public class Unsafe
{
/**
* Enables or disables garbage collection. <em>Warning:</em> you will
* be fucked if you leave it disabled for too long. Do not do this
* unless you are dang sure about what you're doing and are prepared
* to test your code on every platform this side of Nantucket.
*
* <p> Calls to this method do not nest. Regardless of how many times
* you disable GC, only one call is required to reenable it.
*/
public static void setGCEnabled (boolean enabled)
{
// we don't support nesting, NOOP if the state doesn't change
if (isLoaded()) {
if (!_initialized && !(_initialized = init())) {
// no joy initializing things
return;
}
if (_initialized && enabled != _gcEnabled) {
_gcEnabled = enabled;
if (_gcEnabled) {
enableGC();
} else {
disableGC();
}
}
}
}
/**
* Causes the current thread to block for the specified number of
* milliseconds. This exists primarily to work around the fact that on
* Linux, {@link Thread#sleep(long)} is only accurate to around 12ms which
* is wholly unacceptable.
*/
public static void sleep (int millis)
{
if (RunAnywhere.isLinux() && isLoaded()) {
nativeSleep(millis);
} else {
try {
Thread.sleep(millis);
} catch (InterruptedException ie) {
log.info("Thread.sleep(" + millis + ") interrupted.");
}
}
}
/**
* Sets the process' uid to the specified value.
*
* @return true if the uid was changed, false if we were unable to do so.
*/
public static boolean setuid (int uid)
{
if (!RunAnywhere.isWindows() && isLoaded()) {
return nativeSetuid(uid);
}
return false;
}
/**
* Sets the process' gid to the specified value.
*
* @return true if the gid was changed, false if we were unable to do so.
*/
public static boolean setgid (int gid)
{
if (!RunAnywhere.isWindows() && isLoaded()) {
return nativeSetgid(gid);
}
return false;
}
/**
* Sets the process' effective uid to the specified value.
*
* @return true if the euid was changed, false if we were unable to do so.
*/
public static boolean seteuid (int uid)
{
if (!RunAnywhere.isWindows() && isLoaded()) {
return nativeSeteuid(uid);
}
return false;
}
/**
* Sets the process' effective gid to the specified value.
*
* @return true if the egid was changed, false if we were unable to do so.
*/
public static boolean setegid (int gid)
{
if (!RunAnywhere.isWindows() && isLoaded()) {
return nativeSetegid(gid);
}
return false;
}
/**
* Returns true if the native library was successfully loaded, and if this is the first time
* it's been checked and it failed, reports the failure.
*/
protected static boolean isLoaded ()
{
if (_loadError != null) {
log.warning("Unable to load 'unsafe' library", "e", _loadError);
_loadError = null;
}
return _loaded;
}
/**
* Reenable garbage collection after a call to {@link #disableGC}.
*/
protected static native void enableGC ();
/**
* Disables garbage collection.
*/
protected static native void disableGC ();
/**
* Sleeps the current thread for the specified number of milliseconds.
*/
protected static native void nativeSleep (int millis);
/**
* Calls through to the native OS system call to change our uid.
*/
protected static native boolean nativeSetuid (int uid);
/**
* Calls through to the native OS system call to change our gid.
*/
protected static native boolean nativeSetgid (int gid);
/**
* Calls through to the native OS system call to change our euid.
*/
protected static native boolean nativeSeteuid (int uid);
/**
* Calls through to the native OS system call to change our egid.
*/
protected static native boolean nativeSetegid (int gid);
/**
* Called to initialize our library.
*/
protected static native boolean init ();
/** The current state of GC enablement. */
protected static boolean _gcEnabled = true;
/** Whether or not we were able to load our library. */
protected static boolean _loaded;
/** Whether or not we were able to initialize our library (i.e. get access to jvmpi) */
protected static boolean _initialized;
/**
* The error that occurred when loading the native library, or null if none occurred or it was
* already reported.
*/
protected static Throwable _loadError;
static {
try {
System.loadLibrary("unsafe");
_loaded = true;
} catch (Throwable t) {
_loadError = t;
}
}
}
@@ -1,49 +0,0 @@
#
# $Id: Makefile 3331 2005-02-03 01:25:21Z mdb $
NAME=unsafe
#
# Executable definitions
CC=i586-mingw32msvc-gcc
RM=rm
CP=cp
MKDIR=mkdir
DLLWRAP=i586-mingw32msvc-dllwrap
#
# Directory definitions
ROOT=../../../../../../../..
INSTALL_PATH=${ROOT}/dist/lib/i686-Windows
#
# Source files
SRCS = com_threerings_util_unsafe_Unsafe.c
OBJS = ${SRCS:.c=.o}
#
# Parameter and file definitions
INCLUDES=
CFLAGS=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
LDFLAGS=-L/usr/X11R6/lib
LIBS=
TARGET=${NAME}.dll
INSTALL_TARGET=${INSTALL_PATH}/${TARGET}
#
# Target definitions
all: ${INSTALL_TARGET}
${INSTALL_TARGET}: ${OBJS}
@${MKDIR} -p ${INSTALL_PATH}
${DLLWRAP} --output-def ${NAME}.def --add-stdcall-alias \
-o ${INSTALL_TARGET} -s ${OBJS}
clean:
-${RM} ${OBJS}
-${RM} ${INSTALL_TARGET}
@@ -1,80 +0,0 @@
/*
* $Id: com_threerings_util_unsafe_Unsafe.c 3331 2005-02-03 01:25:21Z mdb $
*/
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include "com_threerings_util_unsafe_Unsafe.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Reenabling GC.\n");
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Disabling GC.\n");
jvmpi->DisableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSleep (
JNIEnv* env, jclass clazz, jint millis)
{
/* not supported */
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetuid
(JNIEnv *, jclass, jint)
{
/* not supported */
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetgid
(JNIEnv *, jclass, jint)
{
/* not supported */
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSeteuid (
JNIEnv* env, jclass clzz, jint uid)
{
/* not supported */
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetegid (
JNIEnv* env, jclass clazz, jint gid)
{
/* not supported */
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -1,77 +0,0 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_threerings_util_unsafe_Unsafe */
#ifndef _Included_com_threerings_util_unsafe_Unsafe
#define _Included_com_threerings_util_unsafe_Unsafe
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: enableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_enableGC
(JNIEnv *, jclass);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: disableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_disableGC
(JNIEnv *, jclass);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSleep
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSleep
(JNIEnv *, jclass, jint);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSetuid
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetuid
(JNIEnv *, jclass, jint);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSetgid
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetgid
(JNIEnv *, jclass, jint);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSeteuid
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSeteuid
(JNIEnv *, jclass, jint);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSetegid
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetegid
(JNIEnv *, jclass, jint);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: init
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_init
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
@@ -1,46 +0,0 @@
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
// https://github.com/threerings/nenya
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.util;
import com.threerings.util.unsafe.Unsafe;
/**
* Does something extraordinary.
*/
public class UIDTestApp
{
public static void main (String[] args)
{
if (Unsafe.setuid(1000)) {
System.err.println("Yay! My uid is changed.");
} else {
System.err.println("Boo hoo! I couldn't change my uid.");
}
if (Unsafe.setgid(60)) {
System.err.println("Yay! My gid is changed.");
} else {
System.err.println("Boo hoo! I couldn't change my gid.");
}
try {
Thread.sleep(60*1000L);
} catch (Exception e) {
}
}
}