1 /* 2 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 #include <jni.h> 24 #include "jni_tools.h" 25 26 extern "C" { 27 28 #define FIND_CLASS(_class, _className)\ 29 if (!NSK_JNI_VERIFY(env, (_class = \ 30 env->FindClass(_className)) != NULL))\ 31 return 32 33 #define GET_OBJECT_CLASS(_class, _obj)\ 34 if (!NSK_JNI_VERIFY(env, (_class = \ 35 env->GetObjectClass(_obj)) != NULL))\ 36 return 37 38 #define GET_OBJ_FIELD(_value, _obj, _class, _fieldName, _fieldSig)\ 39 GET_FIELD_ID(field, _class, _fieldName, _fieldSig);\ 40 _value = env->GetObjectField(_obj, field) 41 42 #define GET_FIELD_ID(_fieldID, _class, _fieldName, _fieldSig)\ 43 if (!NSK_JNI_VERIFY(env, (_fieldID = \ 44 env->GetFieldID(_class, _fieldName, _fieldSig)) != NULL))\ 45 return 46 47 #define GET_METHOD_ID(_methodID, _class, _methodName, _sig)\ 48 if (!NSK_JNI_VERIFY(env, (_methodID = \ 49 env->GetMethodID(_class, _methodName, _sig)) != NULL)) \ 50 return 51 52 #define CALL_VOID_NOPARAM(_obj, _class, _methodName)\ 53 GET_METHOD_ID(method, _class, _methodName, "()V");\ 54 if (!NSK_JNI_VERIFY_VOID(env, env->CallVoidMethod(_obj, method))) \ 55 return 56 57 /* 58 * Class: nsk_monitoring_share_thread_MonitorDeadlock_DeadlockThread 59 * Method: nativeLock2 60 * Signature: ()V 61 */ 62 JNIEXPORT void JNICALL Java_nsk_monitoring_share_thread_Deadlock_00024NativeLocker_lock 63 (JNIEnv *env, jobject o) { 64 jclass testBugClass, nativeLockerClass, lockerClass, wicketClass; 65 jobject lock, inner, step1, step2, step3; 66 jfieldID field; 67 jmethodID method; 68 69 GET_OBJECT_CLASS(nativeLockerClass, o); 70 FIND_CLASS(lockerClass, "nsk/monitoring/share/thread/Deadlock$Locker"); 71 FIND_CLASS(wicketClass, "nsk/share/Wicket"); 72 FIND_CLASS(testBugClass, "nsk/share/TestBug"); 73 GET_OBJ_FIELD(lock, o, nativeLockerClass, "lock", "Ljava/lang/Object;"); 74 GET_OBJ_FIELD(step1, o, nativeLockerClass, "step1", "Lnsk/share/Wicket;"); 75 if (step1 == NULL) { 76 env->ThrowNew(testBugClass, "step1 field is null"); 77 return; 78 } 79 GET_OBJ_FIELD(step2, o, nativeLockerClass, "step2", "Lnsk/share/Wicket;"); 80 if (step2 == NULL) { 81 env->ThrowNew(testBugClass, "step2 field is null"); 82 return; 83 } 84 GET_OBJ_FIELD(step3, o, nativeLockerClass, "step3", "Lnsk/share/Wicket;"); 85 if (step3 == NULL) { 86 env->ThrowNew(testBugClass, "step3 field is null"); 87 return; 88 } 89 GET_OBJ_FIELD(inner, o, lockerClass, "inner", "Lnsk/monitoring/share/thread/Deadlock$Locker;"); 90 if (env->MonitorEnter(lock) == JNI_OK) { 91 if (inner == NULL) { 92 env->ThrowNew(testBugClass, "Should not reach here"); 93 } else { 94 CALL_VOID_NOPARAM(step1, wicketClass, "unlock"); 95 CALL_VOID_NOPARAM(step2, wicketClass, "waitFor"); 96 CALL_VOID_NOPARAM(step3, wicketClass, "unlock"); 97 CALL_VOID_NOPARAM(inner, lockerClass, "lock"); 98 } 99 env->MonitorExit(lock); 100 } else { 101 env->ThrowNew(testBugClass, "MonitorEnter(lock) call failed"); 102 } 103 } 104 105 }