1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include "jvmaccess/virtualmachine.hxx"
23 #include "rtl/byteseq.h"
24 #include "rtl/byteseq.hxx"
25 #include "rtl/ref.hxx"
26 #include "sal/types.h"
27 #include "uno/threadpool.h"
33 /* The native implementation part of
34 * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java.
40 Pool(rtl::Reference
< jvmaccess::VirtualMachine
> const & theVirtualMachine
,
41 jmethodID theExecute
, uno_ThreadPool thePool
):
42 virtualMachine(theVirtualMachine
), execute(theExecute
), pool(thePool
) {}
44 rtl::Reference
< jvmaccess::VirtualMachine
> virtualMachine
;
50 Job(Pool
* thePool
, jobject theJob
): pool(thePool
), job(theJob
) {}
56 void throwOutOfMemory(JNIEnv
* env
) {
57 jclass c
= env
->FindClass("java/lang/OutOfMemoryError");
67 static void SAL_CALL
executeRequest(void * data
) {
68 Job
* job
= static_cast< Job
* >(data
);
70 jvmaccess::VirtualMachine::AttachGuard
guard(job
->pool
->virtualMachine
);
71 JNIEnv
* env
= guard
.getEnvironment();
72 // Failure of the following Job.execute Java call is ignored; if that
73 // call fails, it should be due to a java.lang.Error, which is not
74 // handled well, anyway:
75 env
->CallObjectMethod(job
->job
, job
->pool
->execute
);
76 env
->DeleteGlobalRef(job
->job
);
78 } catch (const jvmaccess::VirtualMachine::AttachGuard::CreationException
&) {
79 //TODO: DeleteGlobalRef(job->job)
86 extern "C" SAL_JNI_EXPORT jbyteArray JNICALL
87 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId(
88 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
) SAL_THROW_EXTERN_C()
91 uno_getIdOfCurrentThread(&s
); //TODO: out of memory
92 uno_releaseIdFromCurrentThread();
93 rtl::ByteSequence
seq(s
);
94 rtl_byte_sequence_release(s
);
95 sal_Int32 n
= seq
.getLength();
96 jbyteArray a
= env
->NewByteArray(n
);
97 // sal_Int32 and jsize are compatible here
101 void * p
= env
->GetPrimitiveArrayCritical(a
, 0);
105 memcpy(p
, seq
.getConstArray(), n
);
106 // sal_Int8 and jbyte ought to be compatible
107 env
->ReleasePrimitiveArrayCritical(a
, p
, 0);
111 extern "C" SAL_JNI_EXPORT jlong JNICALL
112 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create(
113 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
) SAL_THROW_EXTERN_C()
116 if (env
->GetJavaVM(&vm
) != JNI_OK
) { //TODO: no Java exception raised?
117 jclass c
= env
->FindClass("java/lang/RuntimeException");
119 env
->ThrowNew(c
, "JNI GetJavaVM failed");
123 jclass c
= env
->FindClass("com/sun/star/lib/uno/environments/remote/Job");
127 jmethodID execute
= env
->GetMethodID(c
, "execute", "()Ljava/lang/Object;");
132 return reinterpret_cast< jlong
>(new Pool(
133 new jvmaccess::VirtualMachine(vm
, env
->GetVersion(), false, env
),
134 execute
, uno_threadpool_create()));
135 } catch (const std::bad_alloc
&) {
136 throwOutOfMemory(env
);
141 extern "C" SAL_JNI_EXPORT
void JNICALL
142 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach(
143 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
)
146 uno_threadpool_attach(reinterpret_cast< Pool
* >(pool
)->pool
);
149 extern "C" SAL_JNI_EXPORT jobject JNICALL
150 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter(
151 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
, jlong pool
) SAL_THROW_EXTERN_C()
154 uno_threadpool_enter(
155 reinterpret_cast< Pool
* >(pool
)->pool
,
156 reinterpret_cast< void ** >(&job
));
160 jobject ref
= env
->NewLocalRef(job
);
161 env
->DeleteGlobalRef(job
);
165 extern "C" SAL_JNI_EXPORT
void JNICALL
166 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach(
167 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
)
170 uno_threadpool_detach(reinterpret_cast< Pool
* >(pool
)->pool
);
173 extern "C" SAL_JNI_EXPORT
void JNICALL
174 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob(
175 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
, jlong pool
, jbyteArray threadId
,
176 jobject job
, jboolean request
, jboolean oneWay
) SAL_THROW_EXTERN_C()
178 void * s
= env
->GetPrimitiveArrayCritical(threadId
, 0);
182 rtl::ByteSequence
seq(
183 static_cast< sal_Int8
* >(s
), env
->GetArrayLength(threadId
));
184 // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are
186 //TODO: out of memory
187 env
->ReleasePrimitiveArrayCritical(threadId
, s
, JNI_ABORT
);
188 Pool
* p
= reinterpret_cast< Pool
* >(pool
);
189 jobject ref
= env
->NewGlobalRef(job
);
195 j
= new(std::nothrow
) Job(p
, ref
);
197 env
->DeleteGlobalRef(ref
);
198 throwOutOfMemory(env
);
202 uno_threadpool_putJob(
203 p
->pool
, seq
.getHandle(),
204 request
? static_cast< void * >(j
) : static_cast< void * >(ref
),
205 request
? executeRequest
: 0, oneWay
);
208 extern "C" SAL_JNI_EXPORT
void JNICALL
209 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose(
210 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
)
213 uno_threadpool_dispose(reinterpret_cast< Pool
* >(pool
)->pool
);
216 extern "C" SAL_JNI_EXPORT
void JNICALL
217 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy(
218 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
)
221 Pool
* p
= reinterpret_cast< Pool
* >(pool
);
222 uno_threadpool_destroy(p
->pool
);
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */