Skip to content

atexit()/EXIT_RUNTIME and pthreads #9251

@dschuff

Description

@dschuff

There are several current issues with the interaction of various pthreads features and runtime exit (i.e. executing functions registered with atexit() and/or Module.onExit()).

First, what should happen?

  • In general, calling exit() from any thread should cause all atexit-registered destructors to run once. Its man page says that it's not thread safe because it uses a global variable; but presumably if the program can guarantee it only gets called once, then the destructors should run on the calling thread.
  • The man page for pthread_exit says that calling it runs the destructors only after the last thread exits (presumably on the last thread left). pthread_create says that returning from a thread entry point is equivalent to calling pthread_exit.
  • I haven't found a spec that says exactly what's supposed to when main() returns in the presence of threads, but the behavior on Linux seems to be that returning from main() is equivalent to calling exit() and runs the destructors.

In emscripten currently:

  • When pthreads are enabled but no threads are ever created, (or if pthreads are created but never joined), destructors work ✔️
  • However when a thread is created and subsequently joined (using PTHREAD_POOL to keep everything synchronous), the destructor runs, but then later ._emscripten_main_thread_process_queued_calls runs and asserts that the runtime has not been exited. ❌ (actually this failure happens even if no destructor is ever registered).
  • Destructor calling fails anytime the destructors should be run off the main thread:
    • PROXY_TO_PTHREAD=1 when registered and run from the thread that runs main() (even when no threads are created); result is a function signature mismatch with a callstack rooted at worker.onmessage
    • when registered from a pthread_create()ed thread; result is a function signature mismatch with a callstack from the implicit exit() inside callMain()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions