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>
34 /* The native implementation part of
35 * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java.
41 Pool(rtl::Reference
< jvmaccess::VirtualMachine
> theVirtualMachine
,
42 jmethodID theExecute
, uno_ThreadPool thePool
):
43 virtualMachine(std::move(theVirtualMachine
)), execute(theExecute
), pool(thePool
) {}
45 rtl::Reference
< jvmaccess::VirtualMachine
> virtualMachine
;
51 Job(Pool
* thePool
, jobject theJob
): pool(thePool
), job(theJob
) {}
57 void throwOutOfMemory(JNIEnv
* env
) {
58 jclass c
= env
->FindClass("java/lang/OutOfMemoryError");
68 static void executeRequest(void * data
) {
69 Job
* job
= static_cast< Job
* >(data
);
71 jvmaccess::VirtualMachine::AttachGuard
guard(job
->pool
->virtualMachine
);
72 JNIEnv
* env
= guard
.getEnvironment();
73 // Failure of the following Job.execute Java call is ignored; if that
74 // call fails, it should be due to a java.lang.Error, which is not
75 // handled well, anyway:
76 env
->CallObjectMethod(job
->job
, job
->pool
->execute
);
77 env
->DeleteGlobalRef(job
->job
);
79 } catch (const jvmaccess::VirtualMachine::AttachGuard::CreationException
&) {
80 //TODO: DeleteGlobalRef(job->job)
87 extern "C" SAL_JNI_EXPORT jbyteArray JNICALL
88 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId(
89 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
) noexcept
91 sal_Sequence
* s
= nullptr;
92 uno_getIdOfCurrentThread(&s
); //TODO: out of memory
93 uno_releaseIdFromCurrentThread();
94 rtl::ByteSequence
seq(s
);
95 rtl_byte_sequence_release(s
);
96 sal_Int32 n
= seq
.getLength();
97 jbyteArray a
= env
->NewByteArray(n
);
98 // sal_Int32 and jsize are compatible here
102 void * p
= env
->GetPrimitiveArrayCritical(a
, nullptr);
106 memcpy(p
, seq
.getConstArray(), n
);
107 // sal_Int8 and jbyte ought to be compatible
108 env
->ReleasePrimitiveArrayCritical(a
, p
, 0);
112 extern "C" SAL_JNI_EXPORT jlong JNICALL
113 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create(
114 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
) noexcept
117 if (env
->GetJavaVM(&vm
) != JNI_OK
) { //TODO: no Java exception raised?
118 jclass c
= env
->FindClass("java/lang/RuntimeException");
120 env
->ThrowNew(c
, "JNI GetJavaVM failed");
124 jclass c
= env
->FindClass("com/sun/star/lib/uno/environments/remote/Job");
128 jmethodID execute
= env
->GetMethodID(c
, "execute", "()Ljava/lang/Object;");
129 if (execute
== nullptr) {
133 return reinterpret_cast< jlong
>(new Pool(
134 new jvmaccess::VirtualMachine(vm
, env
->GetVersion(), false, env
),
135 execute
, uno_threadpool_create()));
136 } catch (const std::bad_alloc
&) {
137 throwOutOfMemory(env
);
142 extern "C" SAL_JNI_EXPORT
void JNICALL
143 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach(
144 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
) noexcept
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
) noexcept
154 uno_threadpool_enter(
155 reinterpret_cast< Pool
* >(pool
)->pool
,
156 reinterpret_cast< void ** >(&job
));
157 if (job
== nullptr) {
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
) noexcept
169 uno_threadpool_detach(reinterpret_cast< Pool
* >(pool
)->pool
);
172 extern "C" SAL_JNI_EXPORT
void JNICALL
173 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob(
174 JNIEnv
* env
, SAL_UNUSED_PARAMETER jclass
, jlong pool
, jbyteArray threadId
,
175 jobject job
, jboolean request
, jboolean oneWay
) noexcept
177 void * s
= env
->GetPrimitiveArrayCritical(threadId
, nullptr);
181 rtl::ByteSequence
seq(
182 static_cast< sal_Int8
* >(s
), env
->GetArrayLength(threadId
));
183 // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are
185 //TODO: out of memory
186 env
->ReleasePrimitiveArrayCritical(threadId
, s
, JNI_ABORT
);
187 Pool
* p
= reinterpret_cast< Pool
* >(pool
);
188 jobject ref
= env
->NewGlobalRef(job
);
189 if (ref
== nullptr) {
194 j
= new(std::nothrow
) Job(p
, ref
);
196 env
->DeleteGlobalRef(ref
);
197 throwOutOfMemory(env
);
201 uno_threadpool_putJob(
202 p
->pool
, seq
.getHandle(),
203 request
? static_cast< void * >(j
) : static_cast< void * >(ref
),
204 request
? executeRequest
: nullptr, oneWay
);
207 extern "C" SAL_JNI_EXPORT
void JNICALL
208 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose(
209 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
) noexcept
211 uno_threadpool_dispose(reinterpret_cast< Pool
* >(pool
)->pool
);
214 extern "C" SAL_JNI_EXPORT
void JNICALL
215 Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy(
216 SAL_UNUSED_PARAMETER JNIEnv
*, SAL_UNUSED_PARAMETER jclass
, jlong pool
) noexcept
218 Pool
* p
= reinterpret_cast< Pool
* >(pool
);
219 uno_threadpool_destroy(p
->pool
);
223 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */