21 #include "JNIHelper.h"
31 jclass Mutex :: mClass = 0;
32 jmethodID Mutex :: mConstructorMethod = 0;
34 bool Mutex :: mInitialized =
false;
44 JNIEnv *env = JNIHelper::sGetEnv();
51 fprintf(stderr,
"Destroying monitor %p with non-zero spin count\n",
53 while (mSpinCount > 0)
59 env->DeleteGlobalRef(mLock);
69 JNIHelper::sRegisterInitializationCallback(initJavaBindings, 0);
76 Mutex :: initJavaBindings(JavaVM*,
void*)
78 JNIEnv *env = JNIHelper::sGetEnv();
82 jclass cls = env->FindClass(
"java/lang/Object");
87 mConstructorMethod = env->GetMethodID(cls,
"<init>",
"()V");
90 mClass = (jclass) env->NewWeakGlobalRef(cls);
103 JNIEnv *env = JNIHelper::sGetEnv();
107 if (env->ExceptionCheck())
110 throw std::runtime_error(
"pending java exception; not locking");
115 if (env->MonitorEnter(mLock) != JNI_OK)
117 fprintf(stderr,
"Could not enter lock: %p\n", mLock);
118 throw std::runtime_error(
"failed to enter monitor; not locking");
122 if (env->ExceptionCheck()) {
123 env->MonitorExit(mLock);
124 throw std::runtime_error(
"failed to enter monitor due to "
125 "pending exception; not locking");
144 JNIEnv *env = JNIHelper::sGetEnv();
152 throw std::runtime_error(
"unlock attempt on unlocked mutex");
158 if (env->MonitorExit(mLock) != JNI_OK)
163 throw std::runtime_error(
"failed attempt to unlock mutex");
174 jobject newValue = 0;
182 env = JNIHelper::sGetEnv();
191 Mutex::initJavaBindings(JNIHelper::sGetVM(), 0);
193 if (mClass && mConstructorMethod)
195 retval =
new Mutex();
197 throw std::bad_alloc();
200 if (env->ExceptionCheck())
201 throw std::bad_alloc();
204 newValue = env->NewObject(mClass, mConstructorMethod);
206 throw std::bad_alloc();
208 if (env->ExceptionCheck())
209 throw std::bad_alloc();
211 retval->mLock = env->NewGlobalRef(newValue);
214 throw std::bad_alloc();
216 if (env->ExceptionCheck())
217 throw std::bad_alloc();
218 env->DeleteLocalRef(newValue);
223 catch (std::bad_alloc & e)
225 VS_REF_RELEASE(retval);
228 catch (std::exception &e)
230 fprintf(stderr,
"got uncaught error creating mutex: %p", retval);
231 VS_REF_RELEASE(retval);
234 env->DeleteLocalRef(newValue);
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...