Protect static global access with a global flag.
- The global objects are protected by a global flag, during
application teardown.
- The following APIs, which could potentially be called during
application teardown, will be NO-OP if global objects are no
longer alive.
rsContextCreate
rsContextCreateGL
rsContextDestroy
- Added a test of the problematic use-cases.
Detailed discussion:
https://goto.google.com/rs-static-destructor
Bug: 62027113
Test: mm
Test: Before the change to rsApiStubs.cpp, the test hangs during
termination.
Test: After the change to rsApiStubs.cpp, the test passes without any
problems.
Change-Id: I7a43a61d9ccf848c17a88e047e97d087132addda
(cherry picked from commit 296cd02e03565153f7dff971988adf8e8c6c365a)
diff --git a/rsApiStubs.cpp b/rsApiStubs.cpp
index e0753b0..28f1b1e 100644
--- a/rsApiStubs.cpp
+++ b/rsApiStubs.cpp
@@ -57,6 +57,28 @@
// supported on Android are built on top of pthread, std::mutex is safe for them.
static std::mutex contextMapMutex;
+// globalObjAlive is a global flag indicating whether the global objects,
+// contextMap & contextMapMutex, are still alive.
+// For the protected functions during application teardown, this
+// flag will be checked before accessing the global objects.
+static bool globalObjAlive;
+
+// GlobalObjGuard manipulates the globalObjAlive flag during construction and
+// destruction. If the guard object is destroyed, globalObjAlive will be set
+// to false, which will make the protected functions NO-OP.
+// https://goto.google.com/rs-static-destructor
+class GlobalObjGuard {
+ public:
+ GlobalObjGuard() {
+ globalObjAlive = true;
+ }
+
+ ~GlobalObjGuard() {
+ globalObjAlive = false;
+ }
+};
+static GlobalObjGuard guard;
+
// API to find high-level context (RsContextWrapper) given a low level context.
// This API is only intended to be used by RenderScript debugger.
extern "C" RsContext rsDebugGetHighLevelContext(RsContext context) {
@@ -96,6 +118,11 @@
extern "C" RsContext rsContextCreate(RsDevice vdev, uint32_t version, uint32_t sdkVersion,
RsContextType ct, uint32_t flags)
{
+ if (!globalObjAlive) {
+ ALOGE("rsContextCreate is not allowed during process teardown.");
+ return nullptr;
+ }
+
RsHidlAdaptation& instance = RsHidlAdaptation::GetInstance();
RsContext context = instance.GetEntryFuncs()->ContextCreate(vdev, version, sdkVersion, ct, flags);
// Wait for debugger to attach if RS_CONTEXT_WAIT_FOR_ATTACH flag set.
@@ -155,6 +182,10 @@
extern "C" void rsContextDestroy (RsContext ctxWrapper)
{
+ if (!globalObjAlive) {
+ return;
+ }
+
RS_DISPATCH(ctxWrapper, ContextDestroy);
// Lock contextMap when deleting an existing entry.
@@ -683,6 +714,11 @@
RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, uint32_t sdkVersion,
RsSurfaceConfig sc, uint32_t dpi)
{
+ if (!globalObjAlive) {
+ ALOGE("rsContextCreateGL is not allowed during process teardown.");
+ return nullptr;
+ }
+
RsFallbackAdaptation& instance = RsFallbackAdaptation::GetInstance();
RsContext context = instance.GetEntryFuncs()->ContextCreateGL(vdev, version, sdkVersion, sc, dpi);