ndk-samples icon indicating copy to clipboard operation
ndk-samples copied to clipboard

Potential issue with standard main loop in NDK samples

Open SysReset opened this issue 11 months ago • 1 comments

The main loop used in many Android NDK samples follows this standard structure:

void android_main(android_app* state)
{
    ...

    while (!state->destroyRequested) {
        android_poll_source* source = nullptr;
        int result = ALooper_pollOnce(g_engine.IsReady() ? 0 : -1, nullptr, nullptr, (void**)&source);
        if (result == ALOOPER_POLL_ERROR)
            break;

        if (source != nullptr)
            source->process(state, source);

        // Issue: This code is executed even after state->destroyRequested is set to true
        if (g_engine.IsReady())
            g_engine.DrawFrame();
    }

    ...
}

Issue: state->destroyRequested is set to true in source->process(state, source) when a "destroy" event occurs. However, the code continues executing after state->destroyRequested is set which can lead to undefined behavior, e.g. accessing released resources.

Potential Fix:

android_poll_source* source;
while (ALooper_pollOnce(g_engine.IsReady() ? 0 : -1, nullptr, nullptr, reinterpret_cast<void**>(&source)) != ALOOPER_POLL_ERROR) {
    if (source != nullptr) {
        source->process(state, source);

        // Exit loop immediately after destroy is requested
        if (state->destroyRequested != 0)
            break;
    }

    if (g_engine.IsReady())
        g_engine.DrawFrame();
}

SysReset avatar Jan 30 '25 19:01 SysReset

I'm waiting to hear back from someone in Android that should know more, but is this actually a problem? Where's it documented that the loop must exit immediately?

DanAlbert avatar Feb 03 '25 23:02 DanAlbert