⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gthread-jni.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  threadNum = (*env)->CallStaticIntMethod    (env, runner_class, runner_threadToThreadID_mth, thread);  if (MAYBE_BROKEN (env, "cannot get ThreadID for a Thread "))    {      threadNum = -1;      goto done;    }  SHOW_OLD_TROUBLE ();done:  return (gpointer) threadNum;}/************************************************************************//* The Actual JNI functions that we pass to the function vector.	*//************************************************************************//************************************************************************//* Mutex Functions                                                  	*//************************************************************************//*** Mutex Utilities  ****/struct mutexObj_cache{  jobject lockForPotentialLockersObj;	/* Lock for the potentialLockers					   field.  Local reference. */  jobject lockObj;		/* The real lock we use.  This is a GLOBAL				   reference and must not be freed. */};/* Initialize the cache of sub-locks for a particular mutex object.  -1 on error, 0 on success.  The caller is not responsible for freeing the   partially-populated cache in case of failure (but in practice does anyway)   (This actually never fails, though, since GetObjectField allegedly never   fails.)     Guaranteed to leave all fields of the cache initialized, even if only to   zero. */static intpopulate_mutexObj_cache (JNIEnv * env, jobject mutexObj,			 struct mutexObj_cache *mcache){  mcache->lockObj = mutexObj;	/* the mutexObj is its own lock.  */  assert (mcache->lockObj);  mcache->lockForPotentialLockersObj = (*env)->GetObjectField    (env, mutexObj, mutex_lockForPotentialLockers_fld);  /* GetObjectField can never fail. */  /*  Retrieving a NULL object could only happen if we somehow got a      a mutex object that was not properly intialized. */   assert (mcache->lockForPotentialLockersObj);  return 0;}/* Clean out the mutexObj_cache, even if it was never populated. */static voidclean_mutexObj_cache (JNIEnv * env, struct mutexObj_cache *mcache){  /* OK to pass NULL refs to DELETE_LOCAL_REF */  DELETE_LOCAL_REF (env, mcache->lockForPotentialLockersObj);  /* mcache->lockObj is a GLOBAL reference. */  mcache->lockObj = NULL;}/* -1 on failure, 0 on success.   The mutexObj_cache is already populated for this particular object. */static intmutexObj_lock (JNIEnv * env, jobject mutexObj, struct mutexObj_cache *mcache){  jint potentialLockers;  if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj))    return -1;  assert(mutexObj);  potentialLockers =     (*env)->GetIntField (env, mutexObj, mutex_potentialLockers_fld);  /* GetIntField() never fails. */  ++potentialLockers;  (*env)->SetIntField    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);  if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj))    return -1;  if (ENTER_MONITOR (env, mcache->lockObj))    return -1;  SHOW_OLD_TROUBLE ();  return 0;}/* Unlock a GMutex, once we're already in JNI and have already gotten the   mutexObj for it.  This skips the messages that TRACE_API_CALLS would   print.   Returns -1 on error, 0 on success. */static intmutexObj_unlock (JNIEnv * env, jobject mutexObj,		 struct mutexObj_cache *mcache){  jint potentialLockers;  int ret = -1;			/* assume failure until we suceed.  */  /* Free the lock first, so that someone waiting for the lock can get it     ASAP. */  /* This is guaranteed not to block. */  if (EXIT_MONITOR (env, mcache->lockObj) < 0)    goto done;  /* Kick down potentialLockers by one.  We do this AFTER we free the lock, so     that we hold it no longer than necessary. */  if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)    goto done;  potentialLockers = (*env)->GetIntField    (env, mutexObj, mutex_potentialLockers_fld);  /* GetIntField never fails */  assert (potentialLockers >= 1);  --potentialLockers;  (*env)->SetIntField    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);  /* Never fails, so the JNI book says. */  /* Clean up. */  if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)    goto done;  ret = 0;done:  return ret;}/*** Mutex Implementations ****//* Create a mutex, which is a java.lang.Object for us.   In case of failure, we'll return NULL.  Which will implicitly    cause future calls to fail. */static GMutex *mutex_new_jni_impl (void){  jobject mutexObj;  JNIEnv *env;  union env_union e;  if (TRACE_API_CALLS)    tracing ("mutex_new_jni_impl()");  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (setup_cache (env) < 0)    {      mutexObj = NULL;      goto done;    }  mutexObj = allocateMutexObject (env);done:  if (TRACE_API_CALLS)    tracing (" ==> %p \n", mutexObj);  return (GMutex *) mutexObj;}/* Lock a mutex. */static voidmutex_lock_jni_impl (GMutex * mutex){  struct mutexObj_cache mcache;  jobject mutexObj = (jobject) mutex;  JNIEnv *env;  union env_union e;  if (TRACE_API_CALLS)    tracing ("mutex_lock_jni_impl( mutexObj = %p )", mutexObj);  assert (mutexObj);  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (setup_cache (env) < 0)    goto done;  HIDE_OLD_TROUBLE (env);  if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)    goto done;  mutexObj_lock (env, mutexObj, &mcache);  /* No need to error check; we've already reported it in any case. */done:  clean_mutexObj_cache (env, &mcache);  if (TRACE_API_CALLS)    tracing (" ==> VOID \n");}/*  Try to lock a mutex.  Return TRUE if we succeed, FALSE if we fail.      FALSE on error. */static gbooleanmutex_trylock_jni_impl (GMutex * gmutex){  jobject mutexObj = (jobject) gmutex;  jint potentialLockers;  gboolean ret = FALSE;  JNIEnv *env;  union env_union e;  struct mutexObj_cache mcache;  if (TRACE_API_CALLS)    tracing ("mutex_trylock_jni_impl(mutexObj=%p)", mutexObj);  assert (mutexObj);  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (setup_cache (env) < 0)    goto done;  HIDE_OLD_TROUBLE (env);  if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)    goto done;  if (ENTER_MONITOR (env, mcache.lockForPotentialLockersObj))    goto done;  potentialLockers = (*env)->GetIntField    (env, mutexObj, mutex_potentialLockers_fld);  assert (potentialLockers >= 0);  if (potentialLockers)    {      /* Already locked.  Clean up and leave. */      EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);	      /* Ignore any error code from EXIT_MONITOR; there's nothing we could do	 at this level, in any case. */      goto done;    }  /* Guaranteed not to block. */  if (ENTER_MONITOR (env, mcache.lockObj))    {      /* Clean up the existing lock. */      EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);	      /* Ignore any error code from EXIT_MONITOR; there's nothing we could do	 at this level, in any case. */      goto done;    }    /* We have the monitor.  Record that fact. */  potentialLockers = 1;  (*env)->SetIntField    (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);  /* Set*Field() never fails */  ret = TRUE;			/* We have the lock. */  /* Clean up. */  if (EXIT_MONITOR (env, mcache.lockForPotentialLockersObj))      goto done;		/* If we fail at this point, still keep the				   main lock.  */  SHOW_OLD_TROUBLE ();done:  clean_mutexObj_cache (env, &mcache);  if (TRACE_API_CALLS)    tracing (" ==> %s\n", ret ? "TRUE" : "FALSE");  return ret;}/* Unlock a mutex. */static voidmutex_unlock_jni_impl (GMutex * gmutex){  jobject mutexObj = (jobject) gmutex;  struct mutexObj_cache mcache;  JNIEnv *env;  union env_union e;  if (TRACE_API_CALLS)    tracing ("mutex_unlock_jni_impl(mutexObj=%p)", mutexObj);  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (setup_cache (env) < 0)    goto done;  HIDE_OLD_TROUBLE (env);  assert (mutexObj);  if ( populate_mutexObj_cache (env, mutexObj, &mcache) < 0)    goto done;  (void) mutexObj_unlock (env, mutexObj, &mcache);  SHOW_OLD_TROUBLE ();done:  clean_mutexObj_cache (env, &mcache);  if (TRACE_API_CALLS)    tracing (" ==> VOID\n");}/* Free a mutex (isn't C fun?).  OK this time for it to be NULL.     No failure conditions, for a change.  */static voidmutex_free_jni_impl (GMutex * mutex){  jobject mutexObj = (jobject) mutex;  JNIEnv *env;  union env_union e;  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (TRACE_API_CALLS)    tracing ("mutex_free_jni_impl(%p)", mutexObj);  freeObject (env, mutexObj);  if (TRACE_API_CALLS)    tracing (" ==> VOID\n");}/************************************************************************//* Condition variable code		     				*//************************************************************************//* Create a new condition variable.  This is a java.lang.Object for us. */static GCond *cond_new_jni_impl (void){  jobject condObj;  JNIEnv *env;  union env_union e;  if (TRACE_API_CALLS)    tracing ("mutex_free_jni_impl()");  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  condObj = allocatePlainObject (env);  if (TRACE_API_CALLS)    tracing (" ==> %p\n", condObj);  return (GCond *) condObj;}/*  Signal on a condition variable.  This is simply calling Object.notify * for us. */static voidcond_signal_jni_impl (GCond * gcond){  JNIEnv *env;  union env_union e;  jobject condObj = (jobject) gcond;  if (TRACE_API_CALLS)    tracing ("cond_signal_jni_impl(condObj = %p)", condObj);  e.jni_env = &env;  (*the_vm)->GetEnv (the_vm, e.void_env, JNI_VERSION_1_1);  if (setup_cache (env) < 0)    goto done;  HIDE_OLD_TROUBLE (env);  assert (condObj);  /* Must have locked an object to call notify */  if (ENTER_MONITOR (env, condObj))    goto done;  (*env)->CallVoidMethod (env, condObj, obj_notify_mth);  if (MAYBE_BROKEN (env, "cannot signal mutex with Object.notify()"))    {      if (EXIT_MONITOR (env, condObj))	BADLY_BROKEN1 ("Failed to unlock a monitor; the VM may deadlock.");      goto done;    }  EXIT_MONITOR (env, condObj);  SHOW_OLD_TROUBLE ();done:  if (TRACE_API_CALLS)    tracing (" ==> VOID\n");}/*  Broadcast to all waiting on a condition variable.  This is simply  * calling Object.notifyAll for us. */static voidcond_broadcast_jni_impl (GCond * gcond){  jobject condObj = (jobject) gcond;  JNIEnv *env;  union env_union e;  if (TRACE_API_CALLS)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -