#105077# managing JNI_info object lifecycle via lifecycle of vm
This commit is contained in:
parent
5a526d0957
commit
ab7e01f652
5 changed files with 142 additions and 91 deletions
|
@ -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:
|
||||
*;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue