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

📄 gthread-jni.c

📁 gcc的组建
💻 C
📖 第 1 页 / 共 5 页
字号:
/* gthread-jni.c -- JNI threading routines for GLIB   Copyright (C) 1998, 2004 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING.  If not, write to theFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA02110-1301 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library.  Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule.  An independent module is a module which is not derived fromor based on this library.  If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so.  If you do not wish to do so, delete thisexception statement from your version. *//************************************************************************//* Header				     				*//************************************************************************//* * @author Julian Dolby (dolby@us.ibm.com) * @date February 7, 2003  implemented for GLIB v.1 *  * * @author Steven Augart  * <steve+classpath at augart dot com>, <augart at watson dot ibm dot com> * @date April 30, 2004 -- May 10 2004: Support new functions for Glib v.2, * fix cond_wait to free and re-acquire the mutex, * replaced trylock stub implementation with a full one. * *  This code implements the GThreadFunctions interface for GLIB using  * Java threading primitives.  All of the locking and conditional variable * functionality required by GThreadFunctions is implemented using the * monitor and wait/notify functionality of Java objects.  The thread- * local functionality uses the java.lang.ThreadLocal class.  * *  Classpath's AWT support uses GTK+ peers.  GTK+ uses GLIB.  GLIB by default * uses the platform's native threading model -- pthreads in most cases.  If * the Java runtime doesn't use the native threading model, then it needs this * code in order to use Classpath's (GTK+-based) AWT routines. * *  This code should be portable; I believe it makes no assumptions * about the underlying VM beyond that it implements the JNI functionality * that this code uses. * *  Currently, use of this code is governed by the configuration option * --enable-portable-native-sync.  We will soon add a VM hook so the VM can * select which threading model it wants to use at run time; at that point, * the configuration option will go away. * * The code in this file uses only JNI 1.1, except for one JNI 1.2 function: * GetEnv, in the JNI Invocation API.  (There seems to be no way around using * GetEnv). * * ACKNOWLEDGEMENT: *  *  I would like to thank Mark Wielaard for his kindness in spending at least * six hours of his own time in reviewing this code and correcting my GNU * coding and commenting style.  --Steve Augart * * * NOTES: * *  This code has been tested with Jikes RVM and with Kaffe. * *  This code should have proper automated unit tests.  I manually tested it *  by running an application that uses AWT. --Steven Augart * * MINOR NIT: * *  - Using a jboolean in the arglist to "throw()" and "rethrow()" *    triggers many warnings from GCC's -Wconversion operation, because that *    is not the same as the conversion (upcast to an int) that would occur in *    the absence of a prototype. *     *    It would be very slightly more efficient to just pass the jboolean, but *    is not worth the clutter of messages.  The right solution would be to *    turn off the -Wconversion warning for just this file, *except* that *    -Wconversion also warns you against constructs such as: *        unsigned u = -1; *    and that is a useful warning.  So I went from a "jboolean" to a *    "gboolean"  (-Wconversion is not enabled by default for GNU Classpath, *    but it is in my own CFLAGS, which, for gcc 3.3.3, read: -pipe -ggdb3 -W *    -Wall -Wbad-function-cast -Wcast-align -Wpointer-arith -Wcast-qual *    -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations *    -fkeep-static-consts -fkeep-inline-functions -Wundef -Wwrite-strings *    -Wno-aggregate-return -Wmissing-noreturn -Wnested-externs -Wtrigraphs *    -Wconversion -Wsign-compare -Wno-float-equal -Wmissing-format-attribute *    -Wno-unreachable-code -Wdisabled-optimization ) */#include <config.h>/************************************************************************//* Configuration							*//************************************************************************//** Tracing and Reporting  **/#define TRACE_API_CALLS	    0	/* announce entry and exit into each method,				   by printing to stderr. */#define TRACE_MONITORS      0	/* Every enterMonitor() and exitMonitor() goes				   to stderr. *//** Trouble handling.  There is a discussion below of this.  **/ #define EXPLAIN_TROUBLE	    1	/* Describe any unexpected trouble that				   happens.  This is a superset				   of EXPLAIN_BROKEN, and if set trumps an				   unset EXPLAIN_BROKEN.  It is not a strict				   superset, since at the moment there is no				   TROUBLE that is not also BROKEN.   				   Use criticalMsg() to describe the problem.				 */#define EXPLAIN_BROKEN	    1	/* Describe trouble that is serious enough to				   be BROKEN.  (Right now all trouble is at				   least BROKEN.) *//* There is no EXPLAIN_BADLY_BROKEN definition.  We always explain   BADLY_BROKEN trouble, since there is no other way to report it.  *//** Error Handling  **/#define DIE_IF_BROKEN	    1	/* Dies if serious trouble happens.  There is				   really no non-serious trouble, except				   possibly problems that arise during				   pthread_create, which are reported by a				   GError.				   If you do not set DIE_IF_BROKEN, then				   trouble will raise a Java RuntimeException.				   We probably do want to die right away,				   since anything that's BROKEN really				   indicates a programming error or a				   system-wide error, and that's what the glib				   documentation says you should do in case of				   that kind of error in a glib-style				   function.  But it does work to turn this				   off.  */#if  DIE_IF_BROKEN#define DIE_IF_BADLY_BROKEN 1	/* DIE_IF_BROKEN implies DIE_IF_BADLY_BROKEN */#else#define DIE_IF_BADLY_BROKEN 1	/* Die if the system is badly broken --				   that is, if we have further trouble while				   attempting to throw an exception				   upwards, or if we are unable to generate				   one of the classes we'll need in order to				   throw wrapped exceptions upward.				   If unset, we will print a warning message,				   and limp along anyway.  Not that the system				   is likely to work.  */#endif/** Performance tuning parameters **/#define ENABLE_EXPENSIVE_ASSERTIONS 0	/* Enable expensive assertions? */#define DELETE_LOCAL_REFS   1	/* Whether to delete local references.   				   JNI only guarantees that there wil be 16				   available.  (Jikes RVM provides an number				   only limited by VM memory.)				   Jikes RVM will probably perform faster if				   this is turned off, but other VMs may need				   this to be turned on in order to perform at				   all, or might need it if things change.				   Remember, we don't know how many of those				   local refs might have already been used up				   by higher layers of JNI code that end up				   calling g_thread_self(),				   g_thread_set_private(), and so on.				   We set this to 1 for GNU Classpath, since				   one of our principles is "always go for the				   most robust implementation" */#define  HAVE_JNI_VERSION_1_2   0 /* Assume we don't.  We could				     dynamically check for this.  We will				     assume JNI 1.2 in later versions of				     Classpath.                                       As it stands, the code in this file                                     already needs one JNI 1.2 function:                                     GetEnv, in the JNI Invocation API.				     TODO This code hasn't been tested yet.				     And really hasn't been implemented yet.				     */ /************************************************************************//* Global data				     				*//************************************************************************/#if defined HAVE_STDINT_H#include <stdint.h>		/* provides intptr_t */#elif defined HAVE_INTTYPES_H#include <inttypes.h>#endif#include <stdarg.h>		/* va_list */#include <glib.h>#include "gthread-jni.h"#include <assert.h>		/* assert() *//* For Java thread priority constants. */#include <gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h>/* Since not all JNI header generators actually define constants we define them here explicitly. */#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY 1#endif#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY 5#endif#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY 10#endif/*  The VM handle.  This is set in    Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit */JavaVM *cp_gtk_the_vm;/* Unions used for type punning. */union env_union{  void **void_env;  JNIEnv **jni_env;};union func_union{  void *void_func;  GThreadFunc g_func;};/* Forward Declarations for Functions  */static int threadObj_set_priority (JNIEnv * env, jobject threadObj,				   GThreadPriority gpriority);static void fatalMsg (const char fmt[], ...)     __attribute__ ((format (printf, 1, 2)))     __attribute__ ((noreturn));static void criticalMsg (const char fmt[], ...)     __attribute__ ((format (printf, 1, 2)));static void tracing (const char fmt[], ...)     __attribute__ ((format (printf, 1, 2)));static jint javaPriorityLevel (GThreadPriority priority)     __attribute__ ((const));/************************************************************************//* Trouble-handling, including utilities to reflect exceptions		*//* back to the VM.  Also some status reporting.				*//************************************************************************//* How are we going to handle problems?   There are several approaches:   1)  Report them with the GError mechanism.       (*thread_create)() is the only one of these functions that takes a       GError pointer.  And the only G_THREAD error defined maps onto EAGAIN.       We don't have any errors in our (*thread_create)() implementation that       can be mapped to EAGAIN.  So this idea is a non-starter.   2)  Reflect the exception back to the VM, wrapped in a RuntimeException.       This will fail sometimes, if we're so broken (BADLY_BROKEN) that we       fail to throw the exception.    3)  Abort execution.  This is what the glib functions themselves do for       errors that they can't report via GError.       Enable DIE_IF_BROKEN and/or DIE_IF_BADLY_BROKEN to       make this the default for BROKEN and/or BADLY_BROKEN trouble.   4) Display messages to stderr.  We always do this for BADLY_BROKEN      trouble.  The glib functions do that for errors they can't report via      GError.    There are some complications.   When I attempted to report a problem in g_thread_self() using g_critical (a   macro around g_log(), I found that g_log in turn looks for thread-private   data and calls g_thread_self() again.   We got a segfault, probably due to stack overflow.  So, this code doesn't   use the g_critical() and g_error() functions any more.  Nor do we use   g_assert(); we use the C library's assert() instead.*/#define WHERE __FILE__ ":" G_STRINGIFY(__LINE__) ": "/* This is portable to older compilers that lack variable-argument macros.   This used to be just g_critical(), but then we ran into the error reporting   problem discussed above.*/static voidfatalMsg (const char fmt[], ...){  va_list ap;  va_start (ap, fmt);  vfprintf (stderr, fmt, ap);  va_end (ap);  fputs ("\nAborting execution\n", stderr);  abort ();}static voidcriticalMsg (const char fmt[], ...){  va_list ap;  va_start (ap, fmt);  vfprintf (stderr, fmt, ap);  va_end (ap);  putc ('\n', stderr);}/* Unlike the other two, this one does not append a newline.  This is only   used if one of the TRACE_ macros is defined.  */static voidtracing (const char fmt[], ...){  va_list ap;  va_start (ap, fmt);  vfprintf (stderr, fmt, ap);  va_end (ap);}#define assert_not_reached()						\  do									\    {									\      fputs(WHERE "You should never get here.  Aborting execution.\n", 	\	    stderr);							\      abort();								\    }									\  while(0)#if DIE_IF_BADLY_BROKEN#define BADLY_BROKEN fatalMsg#else#define BADLY_BROKEN criticalMsg/* So, the user may still attempt to recover, even though we do not advise   this. */#endif/* I find it so depressing to have to use C without varargs macros. */#define BADLY_BROKEN_MSG WHERE "Something fundamental"		\	" to GNU Classpath's AWT JNI broke while we were trying to pass up a Java error message"#define BADLY_BROKEN0()				\    BADLY_BROKEN(BADLY_BROKEN_MSG);#define	    BADLY_BROKEN1(msg)			\    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg)#define	    BADLY_BROKEN2(msg, arg)			\    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg)#define	    BADLY_BROKEN3(msg, arg, arg2) 		\    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2)#define	    BADLY_BROKEN4(msg, arg, arg2, arg3) 		\    BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2, arg3)#define DELETE_LOCAL_REF(env, ref) 		\  do 						\    {						\      if ( DELETE_LOCAL_REFS )			\	{					\	  (*env)->DeleteLocalRef (env, ref);	\	  (ref) = NULL;				\	}					\    }						\  while(0)/* Cached info for Exception-wrapping */static jclass runtimeException_class;	/* java.lang.RuntimeException */static jmethodID runtimeException_ctor; /* constructor for it *//* Throw a new RuntimeException.  It may wrap around an existing exception.   1 if we did rethrow, -1 if we had trouble while rethrowing.   isBroken is always true in this case. */static intthrow (JNIEnv * env, jthrowable cause, const char *message,       gboolean isBroken, const char *file, int line){  jstring jmessage;  gboolean describedException = FALSE;	/* Did we already describe the					   exception to stderr or the					   equivalent?   */  jthrowable wrapper;  /* allocate local message in Java */  const char fmt[] = "In AWT JNI, %s (at %s:%d)";  size_t len = strlen (message) + strlen (file) + sizeof fmt + 25;  char *buf;  if (EXPLAIN_TROUBLE || (isBroken && EXPLAIN_BROKEN))    {      criticalMsg ("%s:%d: AWT JNI failure%s: %s\n", file, line,

⌨️ 快捷键说明

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