diff options
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 2 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTDevice.java | 2 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTGattCharacteristic.java | 2 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTGattDescriptor.java | 2 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTGattService.java | 2 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTManager.java | 5 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTNativeDownlink.java | 68 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTDevice.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTGattCharacteristic.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTGattDescriptor.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTGattService.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTManager.cxx | 5 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTNativeDownlink.cxx | 6 |
14 files changed, 72 insertions, 47 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 17b975f9..b10eb02c 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -303,7 +303,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter /* internal */ @Override - protected native void deleteImpl(); + protected native void deleteImpl(long nativeInstance); /* discovery */ diff --git a/java/direct_bt/tinyb/DBTDevice.java b/java/direct_bt/tinyb/DBTDevice.java index 6a0ca25c..8f0b0c4e 100644 --- a/java/direct_bt/tinyb/DBTDevice.java +++ b/java/direct_bt/tinyb/DBTDevice.java @@ -597,7 +597,7 @@ public class DBTDevice extends DBTObject implements BluetoothDevice * </p> */ @Override - protected native void deleteImpl(); + protected native void deleteImpl(long nativeInstance); @Override public native boolean addCharacteristicListener(final GATTCharacteristicListener listener, final BluetoothGattCharacteristic characteristicMatch); diff --git a/java/direct_bt/tinyb/DBTGattCharacteristic.java b/java/direct_bt/tinyb/DBTGattCharacteristic.java index ccca1ae4..bd7f0dea 100644 --- a/java/direct_bt/tinyb/DBTGattCharacteristic.java +++ b/java/direct_bt/tinyb/DBTGattCharacteristic.java @@ -322,6 +322,6 @@ public class DBTGattCharacteristic extends DBTObject implements BluetoothGattCha private native boolean enableValueNotificationsImpl(boolean v); @Override - protected native void deleteImpl(); + protected native void deleteImpl(long nativeInstance); } diff --git a/java/direct_bt/tinyb/DBTGattDescriptor.java b/java/direct_bt/tinyb/DBTGattDescriptor.java index 86b27530..2733f8ba 100644 --- a/java/direct_bt/tinyb/DBTGattDescriptor.java +++ b/java/direct_bt/tinyb/DBTGattDescriptor.java @@ -167,5 +167,5 @@ public class DBTGattDescriptor extends DBTObject implements BluetoothGattDescrip private native boolean writeValueImpl(byte[] argValue) throws BluetoothException; @Override - protected native void deleteImpl(); + protected native void deleteImpl(long nativeInstance); } diff --git a/java/direct_bt/tinyb/DBTGattService.java b/java/direct_bt/tinyb/DBTGattService.java index 3bdb45a8..98081e25 100644 --- a/java/direct_bt/tinyb/DBTGattService.java +++ b/java/direct_bt/tinyb/DBTGattService.java @@ -131,5 +131,5 @@ public class DBTGattService extends DBTObject implements BluetoothGattService private native List<BluetoothGattCharacteristic> getCharacteristicsImpl(); @Override - protected native void deleteImpl(); + protected native void deleteImpl(long nativeInstance); } diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index c74f0706..263b7365 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -43,6 +43,7 @@ import org.tinyb.BluetoothType; public class DBTManager implements BluetoothManager { protected static final boolean DEBUG = BluetoothFactory.DEBUG; + protected static final boolean VERBOSE = BluetoothFactory.VERBOSE; private static volatile boolean isJVMShuttingDown = false; private static final List<Runnable> userShutdownHooks = new ArrayList<Runnable>(); @@ -269,7 +270,7 @@ public class DBTManager implements BluetoothManager private native List<BluetoothAdapter> getAdapterListImpl(); private native void initImpl(final boolean unifyUUID128Bit) throws BluetoothException; - private native void deleteImpl(); + private native void deleteImpl(long nativeInstance); private DBTManager() { initImpl(unifyUUID128Bit); @@ -304,7 +305,7 @@ public class DBTManager implements BluetoothManager a.close(); } adapters.clear(); - deleteImpl(); + deleteImpl(nativeInstance); } } diff --git a/java/direct_bt/tinyb/DBTNativeDownlink.java b/java/direct_bt/tinyb/DBTNativeDownlink.java index d3535ce0..c45bdb23 100644 --- a/java/direct_bt/tinyb/DBTNativeDownlink.java +++ b/java/direct_bt/tinyb/DBTNativeDownlink.java @@ -25,12 +25,15 @@ package direct_bt.tinyb; +import java.util.concurrent.atomic.AtomicBoolean; + import org.tinyb.BluetoothFactory; public abstract class DBTNativeDownlink { - protected long nativeInstance; - private boolean isValid; + private long nativeInstance; + private final AtomicBoolean isValid = new AtomicBoolean(false); + private final Object nativeLock = new Object(); static { BluetoothFactory.checkInitialized(); @@ -39,11 +42,11 @@ public abstract class DBTNativeDownlink protected DBTNativeDownlink(final long nativeInstance) { this.nativeInstance = nativeInstance; - isValid = true; + isValid.set(true); initNativeJavaObject(nativeInstance); } - protected final boolean isValid() { return isValid; } + protected final boolean isValid() { return isValid.get(); } @Override protected void finalize() @@ -52,41 +55,62 @@ public abstract class DBTNativeDownlink } /** - * Deletes the native instance in the following order + * Deletes the {@code nativeInstance} in the following order * <ol> - * <li>Removes this java reference from the native instance</li> - * <li>Deletes the native instance via {@link #deleteImpl()}</li> - * <li>Sets the nativeInstance := 0</li> + * <li>Removes this java reference from the {@code nativeInstance}</li> + * <li>Deletes the {@code nativeInstance} via {@link #deleteImpl(long)}</li> + * <li>Zeros the {@code nativeInstance} reference</li> * </ol> */ - public synchronized void delete() { - if (!isValid) { - return; + public final void delete() { + synchronized (nativeLock) { + if( !isValid.compareAndSet(true, false) ) { + if( DBTManager.DEBUG ) { + System.err.println("JAVA: delete: !valid -> bail: "+getClass().getSimpleName()); + } + return; + } + if( DBTManager.DEBUG ) { + System.err.println("JAVA: delete.0: "+getClass().getSimpleName()+": valid, handle 0x"+Long.toHexString(nativeInstance)); + } + final long _nativeInstance = nativeInstance; + nativeInstance = 0; + deleteNativeJavaObject(_nativeInstance); // will issue notifyDeleted() itself! + deleteImpl(_nativeInstance); + if( DBTManager.DEBUG ) { + System.err.println("JAVA: delete.X: "+getClass().getSimpleName()+": handle 0x"+Long.toHexString(nativeInstance)); + } } - isValid = false; - deleteNativeJavaObject(nativeInstance); - deleteImpl(); - nativeInstance = 0; } /** * Called from native JavaUplink dtor -> JavaGlobalObj dtor, * i.e. native instance destructed in native land. */ - private synchronized void notifyDeleted() { - isValid = false; - nativeInstance = 0; - // System.err.println("***** notifyDeleted: "+getClass().getSimpleName()+": valid "+isValid+" -> false, handle 0x"+Long.toHexString(nativeInstance)+" -> null: "+toString()); + private final void notifyDeleted() { + synchronized (nativeLock) { + final boolean _isValid = isValid.get(); + final long _nativeInstance = nativeInstance; + isValid.set(false); + nativeInstance = 0; + if( DBTManager.DEBUG ) { + System.err.println("JAVA: delete.notifyDeleted: "+getClass().getSimpleName()+", was: valid "+_isValid+", handle 0x"+Long.toHexString(_nativeInstance)+": "+toString()); + } + } } /** * Deletes the native instance. * <p> - * Called via {@link #delete()} and at this point this java reference - * has been removed from the native instance. + * Called via {@link #delete()} and at this point + * <ul> + * <li>this java reference has been removed from the native instance, i.e. {@code JavaUplink}'s {@code javaObjectRef = nullptr}</li> + * <li>the {@link #nativeInstance} reference has been zeroed, but passed as argument for this final native deletion task.</li> + * </ul> * </p> + * @param nativeInstance copy of {@link #nativeInstance} reference, which has been already zeroed. */ - protected abstract void deleteImpl(); + protected abstract void deleteImpl(long nativeInstance); private native void initNativeJavaObject(final long nativeInstance); private native void deleteNativeJavaObject(final long nativeInstance); diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 3a8892d6..5adbefbd 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -507,10 +507,11 @@ jstring Java_direct_1bt_tinyb_DBTAdapter_toStringImpl(JNIEnv *env, jobject obj) return nullptr; } -void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj) +void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); + DBTAdapter *adapter = castInstance<DBTAdapter>(nativeInstance); DBG_PRINT("Java_direct_1bt_tinyb_DBTAdapter_deleteImpl %s", adapter->toString().c_str()); delete adapter; } catch(...) { diff --git a/java/jni/direct_bt/DBTDevice.cxx b/java/jni/direct_bt/DBTDevice.cxx index 55e074cf..e0acb004 100644 --- a/java/jni/direct_bt/DBTDevice.cxx +++ b/java/jni/direct_bt/DBTDevice.cxx @@ -246,10 +246,11 @@ jint Java_direct_1bt_tinyb_DBTDevice_removeAllCharacteristicListener(JNIEnv *env return 0; } -void Java_direct_1bt_tinyb_DBTDevice_deleteImpl(JNIEnv *env, jobject obj) +void Java_direct_1bt_tinyb_DBTDevice_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - DBTDevice *device = getInstance<DBTDevice>(env, obj); + DBTDevice *device = castInstance<DBTDevice>(nativeInstance); device->remove(); // No delete: DBTDevice instance owned by DBTAdapter // However, device->remove() might issue destruction diff --git a/java/jni/direct_bt/DBTGattCharacteristic.cxx b/java/jni/direct_bt/DBTGattCharacteristic.cxx index fb966a93..d7541e2e 100644 --- a/java/jni/direct_bt/DBTGattCharacteristic.cxx +++ b/java/jni/direct_bt/DBTGattCharacteristic.cxx @@ -48,9 +48,10 @@ jstring Java_direct_1bt_tinyb_DBTGattCharacteristic_toStringImpl(JNIEnv *env, jo return nullptr; } -void Java_direct_1bt_tinyb_DBTGattCharacteristic_deleteImpl(JNIEnv *env, jobject obj) { +void Java_direct_1bt_tinyb_DBTGattCharacteristic_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - GATTCharacteristic *characteristic = getInstance<GATTCharacteristic>(env, obj); + GATTCharacteristic *characteristic = castInstance<GATTCharacteristic>(nativeInstance); (void)characteristic; // No delete: Service instance owned by GATTService -> DBTDevice } catch(...) { diff --git a/java/jni/direct_bt/DBTGattDescriptor.cxx b/java/jni/direct_bt/DBTGattDescriptor.cxx index 17a1a118..081fda33 100644 --- a/java/jni/direct_bt/DBTGattDescriptor.cxx +++ b/java/jni/direct_bt/DBTGattDescriptor.cxx @@ -47,9 +47,10 @@ void Java_direct_1bt_tinyb_DBTGattDescriptor_deleteImpl(JNIEnv *env, jobject obj } } -jstring Java_direct_1bt_tinyb_DBTGattDescriptor_toStringImpl(JNIEnv *env, jobject obj) { +jstring Java_direct_1bt_tinyb_DBTGattDescriptor_toStringImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - GATTDescriptor *nativePtr = getInstance<GATTDescriptor>(env, obj); + GATTDescriptor *nativePtr = castInstance<GATTDescriptor>(nativeInstance); JavaGlobalObj::check(nativePtr->getJavaObject(), E_FILE_LINE); return from_string_to_jstring(env, nativePtr->toString()); } catch(...) { diff --git a/java/jni/direct_bt/DBTGattService.cxx b/java/jni/direct_bt/DBTGattService.cxx index f00f9e2f..fcb234e8 100644 --- a/java/jni/direct_bt/DBTGattService.cxx +++ b/java/jni/direct_bt/DBTGattService.cxx @@ -49,9 +49,10 @@ jstring Java_direct_1bt_tinyb_DBTGattService_toStringImpl(JNIEnv *env, jobject o } -void Java_direct_1bt_tinyb_DBTGattService_deleteImpl(JNIEnv *env, jobject obj) { +void Java_direct_1bt_tinyb_DBTGattService_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - GATTService *service = getInstance<GATTService>(env, obj); + GATTService *service = castInstance<GATTService>(nativeInstance); (void)service; // No delete: Service instance owned by DBTDevice } catch(...) { diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx index 560a0f92..3a02540f 100644 --- a/java/jni/direct_bt/DBTManager.cxx +++ b/java/jni/direct_bt/DBTManager.cxx @@ -53,10 +53,11 @@ void Java_direct_1bt_tinyb_DBTManager_initImpl(JNIEnv *env, jobject obj, jboolea } } -void Java_direct_1bt_tinyb_DBTManager_deleteImpl(JNIEnv *env, jobject obj) +void Java_direct_1bt_tinyb_DBTManager_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) { + (void)obj; try { - DBTManager *manager = getInstance<DBTManager>(env, obj); // special: static singleton + DBTManager *manager = castInstance<DBTManager>(nativeInstance); // special: static singleton manager->close(); manager->setJavaObject(nullptr); (void) manager; diff --git a/java/jni/direct_bt/DBTNativeDownlink.cxx b/java/jni/direct_bt/DBTNativeDownlink.cxx index 77afbd7f..934bf0ca 100644 --- a/java/jni/direct_bt/DBTNativeDownlink.cxx +++ b/java/jni/direct_bt/DBTNativeDownlink.cxx @@ -40,9 +40,6 @@ void Java_direct_1bt_tinyb_DBTNativeDownlink_initNativeJavaObject(JNIEnv *env, j { try { JavaUplink *javaUplink = castInstance<JavaUplink>(nativeInstance); - if( nullptr == javaUplink ) { - throw InternalError("NativeInstance JavaUplink is NULL", E_FILE_LINE); - } jclass javaClazz = search_class(env, obj); java_exception_check_and_throw(env, E_FILE_LINE); if( nullptr == javaClazz ) { @@ -67,9 +64,6 @@ void Java_direct_1bt_tinyb_DBTNativeDownlink_deleteNativeJavaObject(JNIEnv *env, (void)obj; try { JavaUplink *javaUplink = castInstance<JavaUplink>(nativeInstance); - if( nullptr == javaUplink ) { - throw InternalError("NativeInstance JavaUplink is NULL", E_FILE_LINE); - } DBG_PRINT("Java_direct_1bt_tinyb_DBTNativeDownlink_deleteNativeJavaObject %p -> %s", javaUplink, javaUplink->toString().c_str()); javaUplink->setJavaObject(nullptr); } catch(...) { |