Skip to content

Commit

Permalink
fix:【jvm】修复 placeholder() 未遍历 m_threads 导致虚拟机无法退出的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
nlifew committed May 2, 2022
1 parent c9e4840 commit ec8abcd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 23 deletions.
29 changes: 16 additions & 13 deletions vm/jvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jenv& jvm::env() const noexcept
jvm::attach_info jvm::DEFAULT_ATTACH_INFO = {
.is_daemon = false,
.vm = nullptr,
.stack_size = 0,
};

template <typename Cmp, typename T>
Expand All @@ -82,24 +83,19 @@ jenv& jvm::attach(attach_info *attach_info) noexcept
LOGE("you can call jvm::attach() only once on one thread\n");
exit(1);
}
auto *env = new (local_env.buff) jenv(this);
auto *env = new (local_env.buff) jenv(this, attach_info->stack_size);
local_env.attach_info = *attach_info;
local_env.inited = this;

std::unique_lock lck(m_mutex);
m_threads.insert(env);

m_threads[env->tid] = env;

if (! attach_info->is_daemon) {
m_active_threads_count ++;
}
if (! m_placeholder_threads.empty()) {
struct Comparator {
bool operator()(pthread_t p, pthread_t q) const noexcept
{
return pthread_equal(p, q);
}
};
fast_erase<Comparator>(m_placeholder_threads, pthread_self());
fast_erase<pthread_equals>(m_placeholder_threads, env->tid);
}
return *env;
}
Expand All @@ -112,11 +108,14 @@ void jvm::detach() noexcept
exit(1);
}

((jenv *) local_env.buff)->~jenv();
jenv *env = (jenv *) local_env.buff;
pthread_t tid = env->tid;

env->~jenv();
local_env.inited = nullptr;

std::unique_lock lck(m_mutex);
m_threads.erase((jenv *) local_env.buff);
m_threads.erase(tid);

if (! local_env.attach_info.is_daemon) {
m_active_threads_count --;
Expand All @@ -129,7 +128,11 @@ void jvm::detach() noexcept
void jvm::placeholder(pthread_t tid) noexcept
{
std::lock_guard lck(m_mutex);
m_placeholder_threads.push_back(tid);

const auto &it = m_threads.find(tid);
if (it == m_threads.end()) {
m_placeholder_threads.push_back(tid);
}
}

void jvm::wait_for() noexcept
Expand All @@ -147,7 +150,7 @@ int jvm::all_threads(std::vector<jenv *> *out) noexcept
if (out != nullptr) {
out->reserve(out->size() + m_threads.size());
for (const auto &it : m_threads) {
out->push_back(it);
out->push_back(it.second);
}
}
return (int) m_threads.size();
Expand Down
20 changes: 10 additions & 10 deletions vm/jvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

#include <mutex>
#include <condition_variable>
#include <unordered_set>
#include <pthread.h>
#include <unordered_map>
#include <vector>
#include <pthread.h>


namespace javsvm
Expand All @@ -34,8 +34,14 @@ class jvm
*/
volatile int m_active_threads_count = 0;

std::unordered_set<jenv*> m_threads;
struct pthread_equals {
bool operator()(const pthread_t &p, const pthread_t &q) const noexcept
{
return pthread_equal(p, q);
}
};

std::unordered_map<pthread_t, jenv*, std::hash<pthread_t>, pthread_equals> m_threads;
std::vector<pthread_t> m_placeholder_threads;
public:
/**
Expand Down Expand Up @@ -93,6 +99,7 @@ class jvm
{
bool is_daemon;
class jvm *vm;
size_t stack_size;
};

static attach_info DEFAULT_ATTACH_INFO;
Expand Down Expand Up @@ -178,13 +185,6 @@ class jvm
* @return 一共有多少线程数
*/
int all_threads(std::vector<jenv*> *out) noexcept;

/**
* 获取附加到该虚拟机实例上的所有线程数
* NOTE: 此函数非线程安全,可用于快速判断
*/
[[nodiscard]]
int threads_count() const noexcept { return (int) m_threads.size(); }
};

} // namespace javsvm
Expand Down

0 comments on commit ec8abcd

Please sign in to comment.