blob: c9110a905d243ce79e4efe1759d06132337f50b6 [file] [log] [blame]
Mathieu Chartierfc7acf92016-01-13 16:20:26 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mathieu Chartier06fd2cf2016-05-05 11:09:58 -070017#include <dlfcn.h>
Mathieu Chartierfc7acf92016-01-13 16:20:26 -080018#include <iostream>
19
20#include "base/casts.h"
21#include "base/macros.h"
22#include "java_vm_ext.h"
23#include "jni_env_ext.h"
24#include "thread-inl.h"
25
26namespace art {
27namespace {
28
29static volatile std::atomic<bool> vm_was_shutdown(false);
30
31extern "C" JNIEXPORT void JNICALL Java_Main_waitAndCallIntoJniEnv(JNIEnv* env, jclass) {
32 // Wait until the runtime is shutdown.
33 while (!vm_was_shutdown.load()) {
34 usleep(1000);
35 }
36 std::cout << "About to call exception check\n";
37 env->ExceptionCheck();
38 LOG(ERROR) << "Should not be reached!";
39}
40
41// NO_RETURN does not work with extern "C" for target builds.
42extern "C" JNIEXPORT void JNICALL Java_Main_destroyJavaVMAndExit(JNIEnv* env, jclass) {
43 // Fake up the managed stack so we can detach.
44 Thread* const self = Thread::Current();
45 self->SetTopOfStack(nullptr);
46 self->SetTopOfShadowStack(nullptr);
47 JavaVM* vm = down_cast<JNIEnvExt*>(env)->vm;
48 vm->DetachCurrentThread();
Mathieu Chartier06fd2cf2016-05-05 11:09:58 -070049 // Open ourself again to make sure the native library does not get unloaded from
50 // underneath us due to DestroyJavaVM. b/28406866
Mathieu Chartier48b2b3e2016-05-05 15:31:12 -070051 void* handle = dlopen(kIsDebugBuild ? "libarttestd.so" : "libarttest.so", RTLD_NOW);
52 CHECK(handle != nullptr);
Mathieu Chartierfc7acf92016-01-13 16:20:26 -080053 vm->DestroyJavaVM();
54 vm_was_shutdown.store(true);
55 // Give threads some time to get stuck in ExceptionCheck.
56 usleep(1000000);
57 if (env != nullptr) {
58 // Use env != nullptr to trick noreturn.
59 exit(0);
60 }
61}
62
63} // namespace
64} // namespace art