Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
8013b2cc2ea3de99207998e3898882d64dfeba6a
[simgrid.git] / src / bindings / java / JavaContext.cpp
1 /* Context switching within the JVM.                                        */
2
3 /* Copyright (c) 2009-2022. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "JavaContext.hpp"
9 #include "jxbt_utilities.hpp"
10 #include "simgrid/Exception.hpp"
11 #include "src/kernel/actor/ActorImpl.hpp"
12
13 #include <functional>
14 #include <utility>
15
16 extern JavaVM* __java_vm;
17
18 XBT_LOG_NEW_DEFAULT_CATEGORY(java, "MSG for Java(TM)");
19
20 namespace simgrid {
21 namespace kernel {
22 namespace context {
23
24 JavaContextFactory::JavaContextFactory() : ContextFactory()
25 {
26   xbt_assert(xbt::binary_name == "java");
27 }
28
29 JavaContextFactory::~JavaContextFactory()=default;
30
31 Context* JavaContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
32 {
33   return this->new_context<JavaContext>(std::move(code), actor);
34 }
35
36 void JavaContextFactory::run_all(std::vector<actor::ActorImpl*> const& actors)
37 {
38   SerialThreadContext::run_all(actors);
39 }
40
41 JavaContext::JavaContext(std::function<void()>&& code, actor::ActorImpl* actor)
42     : SerialThreadContext(std::move(code), actor, false /* not maestro */)
43 {
44   /* ThreadContext already does all we need */
45 }
46
47 void JavaContext::start_hook()
48 {
49   Context::set_current(this); // We need to attach it also for maestro, in contrary to our ancestor
50
51   //Attach the thread to the JVM
52   JNIEnv *env;
53   xbt_assert(__java_vm->AttachCurrentThread((void**)&env, nullptr) == JNI_OK,
54              "The thread could not be attached to the JVM");
55   this->jenv_ = env;
56 }
57
58 void JavaContext::stop()
59 {
60   this->get_actor()->cleanup_from_self();
61
62   /* Unregister the thread from the JVM */
63   JNIEnv* env = this->jenv_;
64   env->DeleteGlobalRef(this->jprocess_);
65   jint error = __java_vm->DetachCurrentThread();
66   if (error != JNI_OK) {
67     /* This is probably a Java thread, ie an actor not created from the XML (and thus from the C++),
68      * but from Java with something like new Process().start().
69      *
70      * We should not even try to detach such threads. Instead, we throw a Java exception that will raise up
71      * until run_jprocess(), IIUC.
72      */
73     jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledError", "Process killed");
74     XBT_DEBUG("Cannot detach the current thread");
75   }
76
77   simgrid::ForcefulKillException::do_throw(); // clean RAII variables with the dedicated exception
78 }
79
80 }}} // namespace simgrid::kernel::context