From: Martin Zaun Date: July 2 2011 10:14am Subject: bzr push into mysql-5.1-telco-7.1 branch (martin.zaun:4276 to 4277) List-Archive: http://lists.mysql.com/commits/140069 Message-Id: <201107021014.p62AEpWg001800@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4277 Martin Zaun 2011-07-02 [merge] merge from ndb-7.1-jtie to ndb-7.1 modified: storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp 4276 Maitrayi Sabaratnam 2011-07-01 [merge] bug#11766870 Merge 70 t0 71 added: storage/ndb/include/kernel/signaldata/GetConfig.hpp storage/ndb/src/common/debugger/signaldata/GetConfig.cpp modified: mysql-test/suite/ndb/r/ndb_config.result mysql-test/suite/ndb/t/ndb_config.test storage/ndb/include/kernel/GlobalSignalNumbers.h storage/ndb/include/kernel/signaldata/SignalData.hpp storage/ndb/include/mgmapi/mgmapi.h storage/ndb/include/ndb_version.h.in storage/ndb/src/common/debugger/signaldata/CMakeLists.txt storage/ndb/src/common/debugger/signaldata/Makefile.am storage/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp storage/ndb/src/common/debugger/signaldata/SignalNames.cpp storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.hpp storage/ndb/src/kernel/vm/Configuration.cpp storage/ndb/src/kernel/vm/Configuration.hpp storage/ndb/src/mgmapi/mgmapi.cpp storage/ndb/src/mgmapi/mgmapi_internal.h storage/ndb/src/mgmsrv/Defragger.hpp storage/ndb/src/mgmsrv/MgmtSrvr.cpp storage/ndb/src/mgmsrv/MgmtSrvr.hpp storage/ndb/src/mgmsrv/Services.cpp storage/ndb/test/ndbapi/testMgm.cpp storage/ndb/tools/ndb_config.cpp === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_idcache_impl.hpp 2011-07-02 10:09:08 +0000 @@ -54,7 +54,7 @@ // --------------------------------------------------------------------------- -// JNI helper functions +// Local JNI helper functions template< typename T > inline T @@ -108,30 +108,120 @@ jniGetMemberID< jfieldID >(JNIEnv * env, /** * Instantiates an info type describing a member of a Java class. */ -#define JTIE_INSTANTIATE_CLASS_MEMBER_INFO( T, CN, MN, MD ) \ - const char * const T::class_name = CN; \ - const char * const T::member_name = MN; \ - const char * const T::member_descriptor = MD; \ - template struct MemberId< T >; \ +#define JTIE_INSTANTIATE_CLASS_MEMBER_INFO( T, CN, MN, MD ) \ + const char * const T::class_name = CN; \ + const char * const T::member_name = MN; \ + const char * const T::member_descriptor = MD; \ + template struct MemberId< T >; \ template struct MemberIdCache< T >; -// XXX document these classes... - +/** + * Provides uniform access to the JNI Field/Method ID of a Java class member + * as described by the member info type 'C'. + * + * This base class does not cache the member ID and the class object, but + * it retrieves the member ID from JNI upon each access; different caching + * strategies are provided by derived classes. + * + * This class (and its derived classes) impose a strict usage pattern. + * For example, given definitions... + * + * // Defines the field info type for MyClass.myField. + * JTIE_DEFINE_FIELD_MEMBER_INFO(_MyClass_myField) + * + * // Provides a (cached) access to field Id of MyClass.myField. + * typedef JniMemberId< _MyClass_myField > MyClass_myField; + * + * any use of a member ID must be bracketed by getClass() and releaseRef(): + * + * // obtain a class reference + * jclass cls = MyClass_myField::getClass(env); + * if (cls == NULL) { + * // exception pending + * } else { + * // get the field ID valid along with the class reference + * jfieldID fid = MyClass_myField::getId(env, cls); + * if (fid == NULL) { + * // exception pending + * } else { + * // OK to access field using 'fid' + * } + * // allow for releasing the class reference + * MyClass_myField::releaseRef(env, cls); + * } + * + * Derived classes implement any caching underneath this usage pattern. + */ template< typename C > struct MemberId { typedef typename C::memberID_t ID_t; - - // number of JNI GetID() invocations + + // number of JNI GetID() invocations for statistics static unsigned long nIdLookUps; + /** + * Allows for storing a (global) class reference. + * + * Usually only called from getClass(), but enables "cache preloading" + * from a (native, static) function called at class initialization. + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - a valid local or global class reference: assert(cls != NULL) + */ static void setClass(JNIEnv * env, jclass cls) { + assert(cls != NULL); (void)env; (void)cls; } + /** + * Returns a JNI Reference to the class declaring the member specified + * by info type 'C'. + * + * Depending upon the underlying caching strategy, a returned reference + * may be local or global, weak or strong; the scope of its use must be + * demarcated by releaseRef(). + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * + * Post condition: + * - return value is + * NULL: + * - this thread has a pending JNI exception (env->ExceptionCheck()) + * otherwise: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - the returned reference is valid (at least) until releaseRef() + */ static jclass getClass(JNIEnv * env) { - return env->FindClass(C::class_name); + assert(env->ExceptionCheck() == JNI_OK); + jclass cls = env->FindClass(C::class_name); + if (cls == NULL) { // break out for better diagnostics + assert(env->ExceptionCheck() != JNI_OK); // exception pending + } else { + assert(env->ExceptionCheck() == JNI_OK); // ok + } + return cls; } + /** + * Returns the JNI Field/Method ID of a Java class member. + * + * The member ID is only valid along with a class object obtained by + * getClass() and before releaseRef(). + * + * Pre condition: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - a valid class reference obtained by getClass(): assert(cls != NULL) + * + * Post condition: + * - return value is + * NULL: + * - this thread has a pending JNI exception (env->ExceptionCheck()) + * otherwise: + * - this thread has no pending JNI exception (!env->ExceptionCheck()) + * - the returned member ID is valid (at least) until releaseRef() + */ static ID_t getId(JNIEnv * env, jclass cls) { assert(cls != NULL); // multithreaded access ok, inaccurate if non-atomic increment @@ -139,71 +229,104 @@ struct MemberId { return jniGetMemberID< ID_t >(env, cls, C::member_name, C::member_descriptor); } - + + /** + * Allows for a class reference to be released along with any member IDs. + * + * Pre condition: + * - a valid class reference obtained by getClass(): assert(cls != NULL) + * - this thread may have a pending JNI exception (env->ExceptionCheck()) + */ static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); env->DeleteLocalRef(cls); } }; +/** + * Base class for caching of JNI Field/Method IDs. + */ template< typename C > struct MemberIdCache : MemberId< C > { typedef typename C::memberID_t ID_t; static ID_t getId(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); + // the cached member id is only valid along with global class ref + assert(env->IsSameObject(gClassRef, NULL) == JNI_FALSE); (void)env; (void)cls; return mid; } protected: + // the cached global (weak or strong) class ref static jclass gClassRef; + + // the cached member id (only valid along with global class ref) static ID_t mid; }; +/** + * Provides caching of JNI Field/Method IDs using weak class references, + * allowing classes to be unloaded when no longer used by Java code. + */ template< typename C > struct MemberIdWeakCache : MemberIdCache< C > { typedef MemberId< C > A; typedef MemberIdCache< C > Base; static void setClass(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); // multithreaded access ok, sets same class/member object - Base::gClassRef = static_cast(env->NewWeakGlobalRef(cls)); + Base::gClassRef = static_cast< jclass >(env->NewWeakGlobalRef(cls)); Base::mid = A::getId(env, cls); } - using Base::getId; - + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { - jclass cls = static_cast(env->NewLocalRef(Base::gClassRef)); + // a weak global class ref may refer to a freed object at any time + // (i.e.: env->IsSameObject(Base::gClassRef, NULL)) + // unless we've obtained a strong (local or global) non-NULL class ref + jclass cls = static_cast< jclass >(env->NewLocalRef(Base::gClassRef)); if (cls == NULL) { + // global class ref was NULL or referencing a freed object cls = A::getClass(env); - setClass(env, cls); + if (cls == NULL) { + // exception pending + } else { + setClass(env, cls); + } } return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); env->DeleteLocalRef(cls); } }; +/** + * Provides caching of JNI Field/Method IDs using strong class references, + * preventing classes from being unloaded even if no longer used by Java code. + */ template< typename C > struct MemberIdStrongCache : MemberIdCache< C > { typedef MemberId< C > A; typedef MemberIdCache< C > Base; - + static void setClass(JNIEnv * env, jclass cls) { - assert (cls != NULL); + assert(cls != NULL); // multithreaded access ok, sets same class/member object - Base::gClassRef = static_cast(env->NewGlobalRef(cls)); + Base::gClassRef = static_cast< jclass >(env->NewGlobalRef(cls)); Base::mid = A::getId(env, cls); } - using Base::getId; - + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { jclass cls = Base::gClassRef; if (cls == NULL) { @@ -212,48 +335,61 @@ struct MemberIdStrongCache : MemberIdCac } return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); + (void)env; (void)cls; } }; +/** + * Provides caching of JNI Field/Method IDs using weak class references + * with preloading (at class initialization) -- VERY TRICKY, NOT SUPPORTED. + */ template< typename C > struct MemberIdPreloadedWeakCache : MemberIdWeakCache< C > { typedef MemberIdWeakCache< C > Base; - - using Base::setClass; - using Base::getId; - + using Base::setClass; // use as inherited (some compiler wanted this) + + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { + // weak global class ref is assumed to be preloaded and valid jclass cls = Base::gClassRef; - assert (cls != NULL); + assert(env->IsSameObject(cls, NULL) == JNI_FALSE); return cls; } - + static void releaseRef(JNIEnv * env, jclass cls) { + assert(cls != NULL); + (void)env; (void)cls; } }; +/** + * Provides caching of JNI Field/Method IDs using strong class references + * with preloading (at class initialization) -- VERY TRICKY, NOT SUPPORTED. + */ template< typename C > struct MemberIdPreloadedStrongCache : MemberIdStrongCache< C > { typedef MemberIdStrongCache< C > Base; - - using Base::setClass; - using Base::getId; - + using Base::setClass; // use as inherited (some compiler wanted this) + + using Base::getId; // use as inherited (some compiler wanted this) + static jclass getClass(JNIEnv * env) { + // strong global class ref is assumed to be preloaded and valid jclass cls = Base::gClassRef; - assert (cls != NULL); + assert(env->IsSameObject(cls, NULL) == JNI_FALSE); return cls; - } + } - using Base::releaseRef; + using Base::releaseRef; // use as inherited (some compiler wanted this) }; -// XXX test with multiple compilation units <-> jtie_lib.hpp - +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp template< typename C > unsigned long MemberId< C > ::nIdLookUps = 0; @@ -265,14 +401,22 @@ template< typename C > typename C::membe // XXX document +/** + * The supported caching strategies for member IDs and class references. + */ enum JniMemberIdCaching { - NO_CACHING, - WEAK_CACHING, - STRONG_CACHING, - WEAK_CACHING_PRELOAD, - STRONG_CACHING_PRELOAD + NO_CACHING + ,WEAK_CACHING + ,STRONG_CACHING +#if 0 // preloaded caching very tricky, not supported at this time + ,WEAK_CACHING_PRELOAD + ,STRONG_CACHING_PRELOAD +#endif // preloaded caching very tricky, not supported at this time }; +/** + * Generic class for member ID access with selection of caching strategy. + */ template< JniMemberIdCaching M, typename C > struct JniMemberId; @@ -288,6 +432,7 @@ template< typename C > struct JniMemberId< STRONG_CACHING, C > : MemberIdStrongCache< C > {}; +#if 0 // preloaded caching very tricky, not supported at this time template< typename C > struct JniMemberId< WEAK_CACHING_PRELOAD, C > : MemberIdPreloadedWeakCache< C > {}; @@ -295,6 +440,7 @@ struct JniMemberId< WEAK_CACHING_PRELOAD template< typename C > struct JniMemberId< STRONG_CACHING_PRELOAD, C > : MemberIdPreloadedStrongCache< C > {}; +#endif // preloaded caching very tricky, not supported at this time // --------------------------------------------------------------------------- === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object.hpp 2011-07-02 10:09:08 +0000 @@ -44,6 +44,13 @@ struct _jtie_Object : _jobject { // XXX, document: type specifying an Object mapping with a class name // trait type wrapping named-parametrized Object mappings for specialization +// XXX make use of +// JTIE_DEFINE_METHOD_MEMBER_INFO( _jtie_ObjectMapper< T > ) +// to replace +// static const char * const class_name; +// static const char * const member_name; +// static const char * const member_descriptor; +// typedef _jmethodID * memberID_t; template< typename J > struct _jtie_ObjectMapper : _jtie_Object { // the name of the Java peer class in the JVM format (i.e., '/'-separated) @@ -55,11 +62,10 @@ struct _jtie_ObjectMapper : _jtie_Object typedef _jmethodID * memberID_t; }; -// XXX can/should these definitions be moves to _lib ? - +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp template< typename J > const char * const _jtie_ObjectMapper< J >::class_name - = J::class_name; + = J::class_name; // XXX static initialization order dependency? template< typename J > const char * const _jtie_ObjectMapper< J >::member_name @@ -214,6 +220,13 @@ const char * const _jtie_ObjectMapper< J #endif // XXX cleanup this unsupported mapping // XXX to document +// XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp +// XXX replace +// template struct MemberId< _jtie_ObjectMapper< T > >; +// template struct MemberIdCache< _jtie_ObjectMapper< T > >; +// with +// JTIE_INSTANTIATE_CLASS_MEMBER_INFO_X(_jtie_ObjectMapper< T >, +// JCN, "", "()V") #define JTIE_INSTANTIATE_PEER_CLASS_MAPPING( T, JCN ) \ const char * const T::class_name = JCN; \ template struct _jtie_ObjectMapper< T >; \ === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_object_impl.hpp 2011-07-02 10:09:08 +0000 @@ -40,14 +40,10 @@ // Defines the field info type for Wrapper.cdelegate. JTIE_DEFINE_FIELD_MEMBER_INFO(_Wrapper_cdelegate) -// XXX fix and test _PRELOAD caching - -// Provides a (cached) access to field Id of Wrapper.cdelegate. +// Provides a (cached) access to field Id of Wrapper.cdelegate. //typedef JniMemberId< NO_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; typedef JniMemberId< WEAK_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; //typedef JniMemberId< STRONG_CACHING, _Wrapper_cdelegate > Wrapper_cdelegate; -//typedef JniMemberId< WEAK_CACHING_PRELOAD, _Wrapper_cdelegate > Wrapper_cdelegate; -//typedef JniMemberId< STRONG_CACHING_PRELOAD, _Wrapper_cdelegate > Wrapper_cdelegate; // XXX consider changing //template< typename C > struct ObjectParam< _jtie_Object *, C * > { === modified file 'storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp' --- a/storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp 2011-02-02 09:52:33 +0000 +++ b/storage/ndb/src/ndbjtie/jtie/jtie_tconv_ptrbybb_impl.hpp 2011-07-02 10:09:08 +0000 @@ -132,7 +132,7 @@ struct ByteBufferPtrParam { } else { // ok s = 0; - c = static_cast(a); + c = static_cast< C * >(a); } } } @@ -333,7 +333,7 @@ getBufferPosition(jtie_j_n_ByteBuffer jb inline void * getByteBufferAddress(jtie_j_n_ByteBuffer jbb, JNIEnv * env) { // get the internal buffer address of direct ByteBuffer - char * a = static_cast(env->GetDirectBufferAddress(jbb)); + char * a = static_cast< char * >(env->GetDirectBufferAddress(jbb)); if (a == NULL) { #ifndef JTIE_BYTEBUFFER_NO_ZERO_CAPACITY_MAPPING // check for direct ByteBuffer of zero-capacity No bundle (reason: useless for push emails).