Tags: NativeScript/android
Tags
fix: lock the remaining process-global state shared across isolates The caches #2020 named (Console timers, ArgConverter, MetadataNode / MetadataReader) were already covered by #2013: Console and ArgConverter moved to per-runtime RuntimeState, MetadataNode got s_nodeCacheMutex, MetadataReader its own StateMutex, and JEnv / MethodCache a shared_mutex each. Auditing the runtime for what actually remained in that class turned up four more. File::Buffer was a single process-wide 1MB scratch buffer that ReadText filled and returned a pointer into. Main and worker runtimes read modules concurrently from their own threads, so one thread's fread overwrote bytes another was still copying out - silent module-source corruption rather than a crash, which is why it never showed up in a tombstone. The buffer also never saved the allocation it appears to save: every caller goes through the std::string overload, which copies out of it on the next line. Reads now go straight into the returned string, and the borrowing overload, which had no callers, is gone. JType::EnsureInstance published *instance before Init had filled clazz, ctor and valueMethodId, so a second thread could find the pointer non-null and call through uninitialised JNI ids - on the hot boxing path. CallbackHandlers::Init runs once per runtime from PrepareV8Runtime, so every worker start rewrote the process-global class and method-id statics, and re-ran MethodCache::Init, while the isolates already running were reading them. MetadataNode::IsJavascriptKeyword filled a function-local static set behind an empty() check, racing reads from every runtime's thread. Also adds the missing ftell < 0 guard on the read path. Verified: arm64-v8a native build, full test suite 1038/1038.
PreviousNext