1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_bridges.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "jvmaccess/virtualmachine.hxx" 32*cdf0e10cSrcweir #include "rtl/byteseq.h" 33*cdf0e10cSrcweir #include "rtl/byteseq.hxx" 34*cdf0e10cSrcweir #include "rtl/memory.h" 35*cdf0e10cSrcweir #include "rtl/ref.hxx" 36*cdf0e10cSrcweir #include "sal/types.h" 37*cdf0e10cSrcweir #include "uno/threadpool.h" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #include "jni.h" 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include <new> 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir /* The native implementation part of 44*cdf0e10cSrcweir * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java. 45*cdf0e10cSrcweir */ 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace { 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir struct Pool { 50*cdf0e10cSrcweir Pool(rtl::Reference< jvmaccess::VirtualMachine > const & theVirtualMachine, 51*cdf0e10cSrcweir jmethodID theExecute, uno_ThreadPool thePool): 52*cdf0e10cSrcweir virtualMachine(theVirtualMachine), execute(theExecute), pool(thePool) {} 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir rtl::Reference< jvmaccess::VirtualMachine > virtualMachine; 55*cdf0e10cSrcweir jmethodID execute; 56*cdf0e10cSrcweir uno_ThreadPool pool; 57*cdf0e10cSrcweir }; 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir struct Job { 60*cdf0e10cSrcweir Job(Pool * thePool, jobject theJob): pool(thePool), job(theJob) {} 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir Pool * pool; 63*cdf0e10cSrcweir jobject job; 64*cdf0e10cSrcweir }; 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir void throwOutOfMemory(JNIEnv * env) { 67*cdf0e10cSrcweir jclass c = env->FindClass("java/lang/OutOfMemoryError"); 68*cdf0e10cSrcweir if (c != 0) { 69*cdf0e10cSrcweir env->ThrowNew(c, ""); 70*cdf0e10cSrcweir } 71*cdf0e10cSrcweir } 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir extern "C" { 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir static void SAL_CALL executeRequest(void * data) { 78*cdf0e10cSrcweir Job * job = static_cast< Job * >(data); 79*cdf0e10cSrcweir try { 80*cdf0e10cSrcweir jvmaccess::VirtualMachine::AttachGuard guard(job->pool->virtualMachine); 81*cdf0e10cSrcweir JNIEnv * env = guard.getEnvironment(); 82*cdf0e10cSrcweir // Failure of the following Job.execute Java call is ignored; if that 83*cdf0e10cSrcweir // call fails, it should be due to a java.lang.Error, which is not 84*cdf0e10cSrcweir // handled well, anyway: 85*cdf0e10cSrcweir env->CallObjectMethod(job->job, job->pool->execute); 86*cdf0e10cSrcweir env->DeleteGlobalRef(job->job); 87*cdf0e10cSrcweir delete job; 88*cdf0e10cSrcweir } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) { 89*cdf0e10cSrcweir //TODO: DeleteGlobalRef(job->job) 90*cdf0e10cSrcweir delete job; 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir extern "C" JNIEXPORT jbyteArray JNICALL 97*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId( 98*cdf0e10cSrcweir JNIEnv * env, jclass) SAL_THROW_EXTERN_C() 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir sal_Sequence * s = 0; 101*cdf0e10cSrcweir uno_getIdOfCurrentThread(&s); //TODO: out of memory 102*cdf0e10cSrcweir uno_releaseIdFromCurrentThread(); 103*cdf0e10cSrcweir rtl::ByteSequence seq(s); 104*cdf0e10cSrcweir rtl_byte_sequence_release(s); 105*cdf0e10cSrcweir sal_Int32 n = seq.getLength(); 106*cdf0e10cSrcweir jbyteArray a = env->NewByteArray(n); 107*cdf0e10cSrcweir // sal_Int32 and jsize are compatible here 108*cdf0e10cSrcweir if (a == 0) { 109*cdf0e10cSrcweir return 0; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir void * p = env->GetPrimitiveArrayCritical(a, 0); 112*cdf0e10cSrcweir if (p == 0) { 113*cdf0e10cSrcweir return 0; 114*cdf0e10cSrcweir } 115*cdf0e10cSrcweir rtl_copyMemory(p, seq.getConstArray(), n); 116*cdf0e10cSrcweir // sal_Int8 and jbyte ought to be compatible 117*cdf0e10cSrcweir env->ReleasePrimitiveArrayCritical(a, p, 0); 118*cdf0e10cSrcweir return a; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir extern "C" JNIEXPORT jlong JNICALL 122*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create( 123*cdf0e10cSrcweir JNIEnv * env, jclass) SAL_THROW_EXTERN_C() 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir JavaVM * vm; 126*cdf0e10cSrcweir if (env->GetJavaVM(&vm) != JNI_OK) { //TODO: no Java exception raised? 127*cdf0e10cSrcweir jclass c = env->FindClass("java/lang/RuntimeException"); 128*cdf0e10cSrcweir if (c != 0) { 129*cdf0e10cSrcweir env->ThrowNew(c, "JNI GetJavaVM failed"); 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir return 0; 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir jclass c = env->FindClass("com/sun/star/lib/uno/environments/remote/Job"); 134*cdf0e10cSrcweir if (c == 0) { 135*cdf0e10cSrcweir return 0; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir jmethodID execute = env->GetMethodID(c, "execute", "()Ljava/lang/Object;"); 138*cdf0e10cSrcweir if (execute == 0) { 139*cdf0e10cSrcweir return 0; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir try { 142*cdf0e10cSrcweir return reinterpret_cast< jlong >(new Pool( 143*cdf0e10cSrcweir new jvmaccess::VirtualMachine(vm, env->GetVersion(), false, env), 144*cdf0e10cSrcweir execute, uno_threadpool_create())); 145*cdf0e10cSrcweir } catch (std::bad_alloc) { 146*cdf0e10cSrcweir throwOutOfMemory(env); 147*cdf0e10cSrcweir return 0; 148*cdf0e10cSrcweir } 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir extern "C" JNIEXPORT void JNICALL 152*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach( 153*cdf0e10cSrcweir JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C() 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir uno_threadpool_attach(reinterpret_cast< Pool * >(pool)->pool); 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir extern "C" JNIEXPORT jobject JNICALL 159*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter( 160*cdf0e10cSrcweir JNIEnv * env, jclass, jlong pool) SAL_THROW_EXTERN_C() 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir jobject job; 163*cdf0e10cSrcweir uno_threadpool_enter( 164*cdf0e10cSrcweir reinterpret_cast< Pool * >(pool)->pool, 165*cdf0e10cSrcweir reinterpret_cast< void ** >(&job)); 166*cdf0e10cSrcweir if (job == 0) { 167*cdf0e10cSrcweir return 0; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir jobject ref = env->NewLocalRef(job); 170*cdf0e10cSrcweir env->DeleteGlobalRef(job); 171*cdf0e10cSrcweir return ref; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir extern "C" JNIEXPORT void JNICALL 175*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach( 176*cdf0e10cSrcweir JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C() 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir uno_threadpool_detach(reinterpret_cast< Pool * >(pool)->pool); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir extern "C" JNIEXPORT void JNICALL 182*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob( 183*cdf0e10cSrcweir JNIEnv * env, jclass, jlong pool, jbyteArray threadId, jobject job, 184*cdf0e10cSrcweir jboolean request, jboolean oneWay) SAL_THROW_EXTERN_C() 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir void * s = env->GetPrimitiveArrayCritical(threadId, 0); 187*cdf0e10cSrcweir if (s == 0) { 188*cdf0e10cSrcweir return; 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir rtl::ByteSequence seq( 191*cdf0e10cSrcweir static_cast< sal_Int8 * >(s), env->GetArrayLength(threadId)); 192*cdf0e10cSrcweir // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are 193*cdf0e10cSrcweir // compatible here 194*cdf0e10cSrcweir //TODO: out of memory 195*cdf0e10cSrcweir env->ReleasePrimitiveArrayCritical(threadId, s, JNI_ABORT); 196*cdf0e10cSrcweir Pool * p = reinterpret_cast< Pool * >(pool); 197*cdf0e10cSrcweir jobject ref = env->NewGlobalRef(job); 198*cdf0e10cSrcweir if (ref == 0) { 199*cdf0e10cSrcweir return; 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir Job * j = 0; 202*cdf0e10cSrcweir if (request) { 203*cdf0e10cSrcweir j = new(std::nothrow) Job(p, ref); 204*cdf0e10cSrcweir if (j == 0) { 205*cdf0e10cSrcweir env->DeleteGlobalRef(ref); 206*cdf0e10cSrcweir throwOutOfMemory(env); 207*cdf0e10cSrcweir return; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir uno_threadpool_putJob( 211*cdf0e10cSrcweir p->pool, seq.getHandle(), 212*cdf0e10cSrcweir request ? static_cast< void * >(j) : static_cast< void * >(ref), 213*cdf0e10cSrcweir request ? executeRequest : 0, oneWay); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir extern "C" JNIEXPORT void JNICALL 217*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose( 218*cdf0e10cSrcweir JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C() 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir uno_threadpool_dispose(reinterpret_cast< Pool * >(pool)->pool); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir extern "C" JNIEXPORT void JNICALL 224*cdf0e10cSrcweir Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy( 225*cdf0e10cSrcweir JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C() 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir Pool * p = reinterpret_cast< Pool * >(pool); 228*cdf0e10cSrcweir uno_threadpool_destroy(p->pool); 229*cdf0e10cSrcweir delete p; 230*cdf0e10cSrcweir } 231