[K/N] Remove certain pthread functions from runnable allow list

^KT-50713

Merge-request: KT-MR-5417
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-01-14 12:20:30 +00:00
committed by Space
parent bb6c6dc45d
commit c15b1ec001
4 changed files with 34 additions and 15 deletions
@@ -245,6 +245,9 @@ void Kotlin_shutdownRuntime() {
if (!needsFullShutdown) { if (!needsFullShutdown) {
auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeRunning, kGlobalRuntimeShutdown); auto lastStatus = compareAndSwap(&globalRuntimeStatus, kGlobalRuntimeRunning, kGlobalRuntimeShutdown);
RuntimeAssert(lastStatus == kGlobalRuntimeRunning, "Invalid runtime status for shutdown"); RuntimeAssert(lastStatus == kGlobalRuntimeRunning, "Invalid runtime status for shutdown");
// The main thread is not doing anything Kotlin anymore, but will stick around to cleanup C++ globals and the like.
// Mark the thread native, and don't make the GC thread wait on it.
kotlin::SwitchThreadState(runtime->memoryState, kotlin::ThreadState::kNative);
return; return;
} }
@@ -91,6 +91,7 @@ int getSourceInfo(void* symbol, SourceInfo *result, int result_len) {
// TODO: this implementation is just a hack, e.g. the result is inexact; // TODO: this implementation is just a hack, e.g. the result is inexact;
// however it is better to have an inexact stacktrace than not to have any. // however it is better to have an inexact stacktrace than not to have any.
NO_INLINE KStdVector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFrames) noexcept { NO_INLINE KStdVector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFrames) noexcept {
NativeOrUnregisteredThreadGuard guard(true);
#if KONAN_NO_BACKTRACE #if KONAN_NO_BACKTRACE
return {}; return {};
#else #else
@@ -133,6 +134,7 @@ NO_INLINE KStdVector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFr
// TODO: this implementation is just a hack, e.g. the result is inexact; // TODO: this implementation is just a hack, e.g. the result is inexact;
// however it is better to have an inexact stacktrace than not to have any. // however it is better to have an inexact stacktrace than not to have any.
NO_INLINE size_t kotlin::internal::GetCurrentStackTrace(size_t skipFrames, std_support::span<void*> buffer) noexcept { NO_INLINE size_t kotlin::internal::GetCurrentStackTrace(size_t skipFrames, std_support::span<void*> buffer) noexcept {
NativeOrUnregisteredThreadGuard guard(true);
#if KONAN_NO_BACKTRACE #if KONAN_NO_BACKTRACE
return {}; return {};
#else #else
@@ -237,6 +239,7 @@ KNativePtr adjustAddressForSourceInfo(KNativePtr address) { return address; }
#endif #endif
KStdVector<KStdString> kotlin::GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept { KStdVector<KStdString> kotlin::GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept {
NativeOrUnregisteredThreadGuard guard(true);
#if KONAN_NO_BACKTRACE #if KONAN_NO_BACKTRACE
KStdVector<KStdString> strings; KStdVector<KStdString> strings;
strings.push_back("<UNIMPLEMENTED>"); strings.push_back("<UNIMPLEMENTED>");
+27 -4
View File
@@ -144,6 +144,7 @@ class Worker {
kind_(kind), kind_(kind),
exceptionHandling_(exceptionHandling) { exceptionHandling_(exceptionHandling) {
name_ = customName != nullptr ? CreateStablePointer(customName) : nullptr; name_ = customName != nullptr ? CreateStablePointer(customName) : nullptr;
kotlin::ThreadStateGuard guard(ThreadState::kNative);
pthread_mutex_init(&lock_, nullptr); pthread_mutex_init(&lock_, nullptr);
pthread_cond_init(&cond_, nullptr); pthread_cond_init(&cond_, nullptr);
} }
@@ -245,9 +246,9 @@ void waitInNativeState(pthread_cond_t* cond,
class Locker { class Locker {
public: public:
explicit Locker(pthread_mutex_t* lock, bool switchThreadState = true) : lock_(lock) { explicit Locker(pthread_mutex_t* lock, bool switchThreadState = true) : lock_(lock), switchThreadState_(switchThreadState) {
if (switchThreadState) { if (switchThreadState) {
kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative, true);
pthread_mutex_lock(lock_); pthread_mutex_lock(lock_);
} else { } else {
// We may need to create a locker when the current thread is already unregistered in the memory subsystem. // We may need to create a locker when the current thread is already unregistered in the memory subsystem.
@@ -255,28 +256,40 @@ public:
pthread_mutex_lock(lock_); pthread_mutex_lock(lock_);
} }
} }
Locker(pthread_mutex_t* lock, MemoryState* memoryState) : lock_(lock) { Locker(pthread_mutex_t* lock, MemoryState* memoryState) : lock_(lock), memoryState_(memoryState) {
kotlin::ThreadStateGuard guard(memoryState, kotlin::ThreadState::kNative); kotlin::ThreadStateGuard guard(memoryState, kotlin::ThreadState::kNative, true);
pthread_mutex_lock(lock_); pthread_mutex_lock(lock_);
} }
~Locker() { ~Locker() {
kotlin::ThreadStateGuard guard;
if (switchThreadState_) {
if (memoryState_ != nullptr) {
guard = kotlin::ThreadStateGuard(memoryState_, ThreadState::kNative, true);
} else {
guard = kotlin::ThreadStateGuard(ThreadState::kNative, true);
}
}
pthread_mutex_unlock(lock_); pthread_mutex_unlock(lock_);
} }
private: private:
pthread_mutex_t* lock_; pthread_mutex_t* lock_;
bool switchThreadState_ = true;
MemoryState* memoryState_ = nullptr;
}; };
class Future { class Future {
public: public:
Future(KInt id) : state_(SCHEDULED), id_(id) { Future(KInt id) : state_(SCHEDULED), id_(id) {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
pthread_mutex_init(&lock_, nullptr); pthread_mutex_init(&lock_, nullptr);
pthread_cond_init(&cond_, nullptr); pthread_cond_init(&cond_, nullptr);
} }
~Future() { ~Future() {
clear(); clear();
kotlin::ThreadStateGuard guard(ThreadState::kNative);
pthread_mutex_destroy(&lock_); pthread_mutex_destroy(&lock_);
pthread_cond_destroy(&cond_); pthread_cond_destroy(&cond_);
} }
@@ -326,6 +339,7 @@ class Future {
class State { class State {
public: public:
State() { State() {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
pthread_mutex_init(&lock_, nullptr); pthread_mutex_init(&lock_, nullptr);
pthread_cond_init(&cond_, nullptr); pthread_cond_init(&cond_, nullptr);
@@ -335,6 +349,7 @@ class State {
} }
~State() { ~State() {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
// TODO: some sanity check here? // TODO: some sanity check here?
pthread_mutex_destroy(&lock_); pthread_mutex_destroy(&lock_);
pthread_cond_destroy(&cond_); pthread_cond_destroy(&cond_);
@@ -527,6 +542,7 @@ class State {
} }
void signalAnyFuture() { void signalAnyFuture() {
kotlin::AssertThreadState(ThreadState::kNative);
{ {
Locker locker(&lock_); Locker locker(&lock_);
currentVersion_++; currentVersion_++;
@@ -535,6 +551,7 @@ class State {
} }
void signalAnyFuture(MemoryState* memoryState) { void signalAnyFuture(MemoryState* memoryState) {
kotlin::AssertThreadState(memoryState, ThreadState::kNative);
{ {
Locker locker(&lock_, memoryState); Locker locker(&lock_, memoryState);
currentVersion_++; currentVersion_++;
@@ -638,6 +655,7 @@ State* theState() {
} }
void Future::storeResultUnlocked(KNativePtr result, bool ok) { void Future::storeResultUnlocked(KNativePtr result, bool ok) {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
{ {
Locker locker(&lock_); Locker locker(&lock_);
state_ = ok ? COMPUTED : THROWN; state_ = ok ? COMPUTED : THROWN;
@@ -651,6 +669,7 @@ void Future::storeResultUnlocked(KNativePtr result, bool ok) {
} }
void Future::cancelUnlocked(MemoryState* memoryState) { void Future::cancelUnlocked(MemoryState* memoryState) {
kotlin::ThreadStateGuard guard(memoryState, ThreadState::kNative);
{ {
Locker locker(&lock_, memoryState); Locker locker(&lock_, memoryState);
state_ = CANCELLED; state_ = CANCELLED;
@@ -896,6 +915,7 @@ Worker::~Worker() {
DisposeStablePointerFor(memoryState_, name_); DisposeStablePointerFor(memoryState_, name_);
} }
kotlin::ThreadStateGuard guard(memoryState_, ThreadState::kNative);
pthread_mutex_destroy(&lock_); pthread_mutex_destroy(&lock_);
pthread_cond_destroy(&cond_); pthread_cond_destroy(&cond_);
} }
@@ -925,10 +945,12 @@ void* workerRoutine(void* argument) {
} // namespace } // namespace
void Worker::startEventLoop() { void Worker::startEventLoop() {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
pthread_create(&thread_, nullptr, workerRoutine, this); pthread_create(&thread_, nullptr, workerRoutine, this);
} }
void Worker::putJob(Job job, bool toFront) { void Worker::putJob(Job job, bool toFront) {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
Locker locker(&lock_); Locker locker(&lock_);
if (toFront) if (toFront)
queue_.push_front(job); queue_.push_front(job);
@@ -938,6 +960,7 @@ void Worker::putJob(Job job, bool toFront) {
} }
void Worker::putDelayedJob(Job job) { void Worker::putDelayedJob(Job job) {
kotlin::ThreadStateGuard guard(ThreadState::kNative);
Locker locker(&lock_); Locker locker(&lock_);
delayed_.insert(job); delayed_.insert(job);
pthread_cond_signal(&cond_); pthread_cond_signal(&cond_);
@@ -144,18 +144,8 @@ extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
"unsetenv", "unsetenv",
"dispatch_once", "dispatch_once",
"\x01_pthread_cond_init",
"_pthread_cond_init",
"pthread_cond_broadcast",
"pthread_cond_destroy",
"pthread_cond_signal",
"pthread_cond_init",
"pthread_create",
"pthread_equal", "pthread_equal",
"pthread_main_np", "pthread_main_np",
"pthread_mutex_destroy",
"pthread_mutex_init",
"pthread_mutex_unlock",
"pthread_self", "pthread_self",
"+[NSMethodSignature signatureWithObjCTypes:]", "+[NSMethodSignature signatureWithObjCTypes:]",
@@ -374,4 +364,4 @@ extern "C" RUNTIME_NOTHROW RUNTIME_NODEBUG void Kotlin_mm_checkStateAtExternalFu
RuntimeFail("Expected kNative thread state at call of function %s by function %s", callee, caller); RuntimeFail("Expected kNative thread state at call of function %s by function %s", callee, caller);
} }
#endif // KONAN_NO_EXTERNAL_CALLS_CHECKER #endif // KONAN_NO_EXTERNAL_CALLS_CHECKER