#105077# managing JNI_info object lifecycle via lifecycle of vm

This commit is contained in:
Daniel Boelzle 2002-12-06 15:29:37 +00:00
parent 5a526d0957
commit ab7e01f652
5 changed files with 142 additions and 91 deletions

View file

@ -5,6 +5,7 @@ UDK_3_1_0 {
component_canUnload;
Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J;
Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call;
Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J;
local:
*;
};

View file

@ -2,9 +2,9 @@
*
* $RCSfile: jni_bridge.cxx,v $
*
* $Revision: 1.7 $
* $Revision: 1.8 $
*
* last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $
* last change: $Author: dbo $ $Date: 2002-12-06 16:29:36 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -210,12 +210,18 @@ void Bridge::acquire() const SAL_THROW( () )
{
if (1 == osl_incrementInterlockedCount( &m_ref ))
{
uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
uno_registerMapping( &mapping, Bridge_free, m_java_env, (uno_Environment *)m_uno_env, 0 );
OSL_ASSERT( mapping == const_cast< Mapping * >( &m_java2uno ) );
mapping = const_cast< Mapping * >( &m_uno2java );
uno_registerMapping( &mapping, Bridge_free, (uno_Environment *)m_uno_env, m_java_env, 0 );
OSL_ASSERT( mapping == const_cast< Mapping * >( &m_uno2java ) );
if (m_registered_java2uno)
{
uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
uno_registerMapping(
&mapping, Bridge_free, m_java_env, (uno_Environment *)m_uno_env, 0 );
}
else
{
uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2java );
uno_registerMapping(
&mapping, Bridge_free, (uno_Environment *)m_uno_env, m_java_env, 0 );
}
}
}
//__________________________________________________________________________________________________
@ -223,18 +229,25 @@ void Bridge::release() const SAL_THROW( () )
{
if (! osl_decrementInterlockedCount( &m_ref ))
{
uno_revokeMapping( const_cast< Mapping * >( &m_java2uno ) );
uno_revokeMapping( const_cast< Mapping * >( &m_uno2java ) );
uno_revokeMapping(
m_registered_java2uno
? const_cast< Mapping * >( &m_java2uno )
: const_cast< Mapping * >( &m_uno2java ) );
}
}
//__________________________________________________________________________________________________
Bridge::Bridge(
uno_Environment * java_env, uno_ExtEnvironment * uno_env )
: m_ref( 0 ),
uno_Environment * java_env, uno_ExtEnvironment * uno_env,
bool registered_java2uno )
: m_ref( 1 ),
m_uno_env( uno_env ),
m_java_env( java_env )
m_java_env( java_env ),
m_registered_java2uno( registered_java2uno )
{
m_jni_info = new JNI_info( this );
JNI_guarded_context jni(
0 /* bootstrapping bridge, no jni_info available */,
reinterpret_cast< ::jvmaccess::VirtualMachine * >( m_java_env->pContext ) );
m_jni_info = JNI_info::get_jni_info( jni );
OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env );
(*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
@ -256,8 +269,6 @@ Bridge::Bridge(
//__________________________________________________________________________________________________
Bridge::~Bridge() SAL_THROW( () )
{
delete m_jni_info;
(*m_java_env->release)( m_java_env );
(*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
@ -401,16 +412,18 @@ void SAL_CALL uno_ext_getMapping(
if (from_env_typename.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ) &&
to_env_typename.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
{
Bridge * bridge = new Bridge( pFrom, pTo->pExtEnv ); // ref count = 0
bridge->acquire(); // 0->1 registers both mappings
Bridge * bridge = new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
mapping = &bridge->m_java2uno;
uno_registerMapping(
&mapping, Bridge_free, pFrom, (uno_Environment *)pTo->pExtEnv, 0 );
}
else if (from_env_typename.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ) &&
to_env_typename.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_JAVA) ))
{
Bridge * bridge = new Bridge( pTo, pFrom->pExtEnv ); // ref count = 0
bridge->acquire(); // 0->1 registers both mappings
Bridge * bridge = new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
mapping = &bridge->m_uno2java;
uno_registerMapping(
&mapping, Bridge_free, (uno_Environment *)pFrom->pExtEnv, pTo, 0 );
}
}
catch (BridgeRuntimeError & err)

View file

@ -2,9 +2,9 @@
*
* $RCSfile: jni_bridge.h,v $
*
* $Revision: 1.5 $
* $Revision: 1.6 $
*
* last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $
* last change: $Author: dbo $ $Date: 2002-12-06 16:29:36 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -93,12 +93,13 @@ struct Bridge
Mapping m_java2uno;
Mapping m_uno2java;
bool m_registered_java2uno;
JNI_info const * m_jni_info;
//
~Bridge() SAL_THROW( () );
Bridge( uno_Environment * java_env, uno_ExtEnvironment * uno_env );
Bridge( uno_Environment * java_env, uno_ExtEnvironment * uno_env, bool registered_java2uno );
void acquire() const;
void release() const;

View file

@ -2,9 +2,9 @@
*
* $RCSfile: jni_info.cxx,v $
*
* $Revision: 1.4 $
* $Revision: 1.5 $
*
* last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $
* last change: $Author: dbo $ $Date: 2002-12-06 16:29:37 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -65,6 +65,8 @@
#include "rtl/strbuf.hxx"
#include "rtl/ustrbuf.hxx"
#include "uno/lbnames.h"
using namespace ::std;
using namespace ::osl;
@ -300,12 +302,12 @@ JNI_type_info::JNI_type_info(
m_jo_type = 0;
}
//__________________________________________________________________________________________________
void JNI_type_info::_delete( JNI_context const & jni, JNI_type_info * that ) SAL_THROW( () )
void JNI_type_info::destroy( JNI_context const & jni )
{
delete [] that->m_fields;
delete [] that->m_methods;
jni->DeleteGlobalRef( that->m_class );
delete that;
delete [] m_fields;
delete [] m_methods;
jni->DeleteGlobalRef( m_class );
delete this;
}
//##################################################################################################
@ -353,7 +355,7 @@ JNI_type_info const * JNI_info::get_type_info(
{
info = holder.m_info;
guard.clear();
JNI_type_info::_delete( jni, new_info );
new_info->destroy( jni );
}
}
else
@ -406,7 +408,7 @@ JNI_type_info const * JNI_info::get_type_info(
{
info = holder.m_info;
guard.clear();
JNI_type_info::_delete( jni, new_info );
new_info->destroy( jni );
}
}
else
@ -417,9 +419,8 @@ JNI_type_info const * JNI_info::get_type_info(
return info;
}
//__________________________________________________________________________________________________
JNI_info::JNI_info( Bridge const * bridge )
: m_bridge( bridge ), // unacquired pointer to owner
m_XInterface_td(
JNI_info::JNI_info( JNI_context const & jni )
: m_XInterface_td(
::getCppuType(
(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > const *)0 ) ),
m_XInterface_queryInterface_td(
@ -432,8 +433,7 @@ JNI_info::JNI_info( Bridge const * bridge )
(::com::sun::star::uno::RuntimeException const *)0 ) ),
m_class_JNI_proxy( 0 )
{
JNI_guarded_context jni(
this, reinterpret_cast< ::jvmaccess::VirtualMachine * >( m_bridge->m_java_env->pContext ) );
// !!!no JNI_info available at JNI_context!!!
// class lookup
JLocalAutoRef jo_Object(
@ -700,7 +700,8 @@ JNI_info::JNI_info( Bridge const * bridge )
OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid );
// get java env
JLocalAutoRef jo_java( jni, ustring_to_jstring( jni, m_bridge->m_java_env->pTypeName ) );
OUString java_env_type_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) );
JLocalAutoRef jo_java( jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
jvalue args[ 2 ];
args[ 0 ].l = jo_java.get();
args[ 1 ].l = 0;
@ -736,55 +737,88 @@ JNI_info::JNI_info( Bridge const * bridge )
m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
}
//__________________________________________________________________________________________________
JNI_info::~JNI_info() SAL_THROW( () )
void JNI_info::destroy( JNI_context const & jni )
{
try
t_str2type::const_iterator iPos( m_type_map.begin() );
t_str2type::const_iterator const iEnd( m_type_map.begin() );
for ( ; iPos != iEnd; ++iPos )
{
JNI_guarded_context jni(
this,
reinterpret_cast< ::jvmaccess::VirtualMachine * >( m_bridge->m_java_env->pContext ) );
iPos->second.m_info->destroy( jni );
}
t_str2type::const_iterator iPos( m_type_map.begin() );
t_str2type::const_iterator const iEnd( m_type_map.begin() );
for ( ; iPos != iEnd; ++iPos )
// free global refs
jni->DeleteGlobalRef( m_object_java_env );
jni->DeleteGlobalRef( m_class_Object );
jni->DeleteGlobalRef( m_class_String );
jni->DeleteGlobalRef( m_class_Double );
jni->DeleteGlobalRef( m_class_Float );
jni->DeleteGlobalRef( m_class_Long );
jni->DeleteGlobalRef( m_class_Integer );
jni->DeleteGlobalRef( m_class_Short );
jni->DeleteGlobalRef( m_class_Byte );
jni->DeleteGlobalRef( m_class_Boolean );
jni->DeleteGlobalRef( m_class_Character );
jni->DeleteGlobalRef( m_class_JNI_proxy );
jni->DeleteGlobalRef( m_class_RuntimeException );
jni->DeleteGlobalRef( m_class_UnoRuntime );
jni->DeleteGlobalRef( m_class_TypeClass );
jni->DeleteGlobalRef( m_class_Type );
jni->DeleteGlobalRef( m_class_Any );
delete this;
}
//__________________________________________________________________________________________________
JNI_info const * JNI_info::get_jni_info( JNI_context const & jni )
{
// !!!no JNI_info available at JNI_context!!!
JLocalAutoRef jo_JNI_info_holder(
jni, find_class( jni, "com/sun/star/bridges/jni_uno/JNI_info_holder" ) );
// field JNI_info_holder.m_jni_info_handle
jfieldID field_s_jni_info_handle =
jni->GetStaticFieldID( (jclass)jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
jni.ensure_no_exception();
OSL_ASSERT( 0 != field_s_jni_info_handle );
JNI_info const * jni_info =
reinterpret_cast< JNI_info const * >(
jni->GetStaticLongField( (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
if (0 == jni_info) // UNinitialized?
{
JNI_info * new_info = new JNI_info( jni );
ClearableMutexGuard guard( Mutex::getGlobalMutex() );
jni_info =
reinterpret_cast< JNI_info const * >(
jni->GetStaticLongField(
(jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
if (0 == jni_info) // still UNinitialized?
{
JNI_type_info::_delete( jni, iPos->second.m_info );
jni->SetStaticLongField( (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle,
reinterpret_cast< jlong >( new_info ) );
jni_info = new_info;
}
else
{
guard.clear();
new_info->destroy( jni );
}
// free global refs
jni->DeleteGlobalRef( m_object_java_env );
jni->DeleteGlobalRef( m_class_Object );
jni->DeleteGlobalRef( m_class_String );
jni->DeleteGlobalRef( m_class_Double );
jni->DeleteGlobalRef( m_class_Float );
jni->DeleteGlobalRef( m_class_Long );
jni->DeleteGlobalRef( m_class_Integer );
jni->DeleteGlobalRef( m_class_Short );
jni->DeleteGlobalRef( m_class_Byte );
jni->DeleteGlobalRef( m_class_Boolean );
jni->DeleteGlobalRef( m_class_Character );
jni->DeleteGlobalRef( m_class_JNI_proxy );
jni->DeleteGlobalRef( m_class_RuntimeException );
jni->DeleteGlobalRef( m_class_UnoRuntime );
jni->DeleteGlobalRef( m_class_TypeClass );
jni->DeleteGlobalRef( m_class_Type );
jni->DeleteGlobalRef( m_class_Any );
}
catch (BridgeRuntimeError & err)
{
#ifdef _DEBUG
OString cstr_msg(
OUStringToOString(
OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) );
OSL_ENSURE( 0, cstr_msg.getStr() );
#endif
}
catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
{
OSL_ENSURE( 0, "[jni_uno bridge error] attaching current thread to java failed!" );
}
return jni_info;
}
}
//##################################################################################################
JNIEXPORT void JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(
JNIEnv * jni_env, jobject jo_proxy, jlong jni_info_handle )
SAL_THROW_EXTERN_C()
{
::jni_uno::JNI_info * jni_info = reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle );
::jni_uno::JNI_context jni( jni_info, jni_env );
jni_info->destroy( jni );
}

View file

@ -2,9 +2,9 @@
*
* $RCSfile: jni_info.h,v $
*
* $Revision: 1.4 $
* $Revision: 1.5 $
*
* last change: $Author: dbo $ $Date: 2002-12-06 10:26:05 $
* last change: $Author: dbo $ $Date: 2002-12-06 16:29:37 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -94,7 +94,9 @@ struct JNI_type_info
JNI_type_info( JNI_context const & jni, typelib_InterfaceTypeDescription * td );
JNI_type_info( JNI_context const & jni, typelib_CompoundTypeDescription * td );
static void _delete( JNI_context const & jni, JNI_type_info * that ) SAL_THROW( () );
void destroy( JNI_context const & jni );
private:
inline ~JNI_type_info() {}
};
//==================================================================================================
struct JNI_type_info_holder
@ -107,12 +109,9 @@ struct JNI_type_info_holder
//==================================================================================================
typedef ::std::hash_map< ::rtl::OUString, JNI_type_info_holder, ::rtl::OUStringHash > t_str2type;
struct Bridge;
//==================================================================================================
class JNI_info
{
Bridge const * m_bridge; // unacquired pointer to owner
mutable ::osl::Mutex m_mutex;
mutable t_str2type m_type_map;
@ -192,10 +191,6 @@ public:
jfieldID m_field_JNI_proxy_m_type;
jfieldID m_field_JNI_proxy_m_oid;
//
~JNI_info() SAL_THROW( () );
JNI_info( Bridge const * bridge );
//
JNI_type_info const * get_type_info(
JNI_context const & jni, typelib_TypeDescription * td ) const;
@ -211,6 +206,13 @@ public:
JNI_context const & jni, jobject javaI, jstring oid, jobject type ) const;
inline void java_env_revokeInterface(
JNI_context const & jni, jstring oid, jobject type ) const;
//
static JNI_info const * get_jni_info( JNI_context const & jni );
void destroy( JNI_context const & jni );
private:
JNI_info( JNI_context const & jni );
inline ~JNI_info() {}
};
//__________________________________________________________________________________________________
inline void JNI_info::append_sig(