blob: 8e4ca4b0c750d281e0ebc0ef84bfa5eb38325e05 [file]
#include <emscripten/emscripten.h>
#include <emscripten/eventloop.h>
#include <emscripten/console.h>
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
_Atomic int ready;
void markReady(void* arg) {
ready = 1;
}
void* thread_main(void* arg) {
int keepalive = (intptr_t)arg;
emscripten_outf("in thread_main: %d", keepalive);
if (keepalive) {
// Exit with live runtime. Once we are in the event loop call markReady.
emscripten_async_call(markReady, NULL, 0);
emscripten_exit_with_live_runtime();
}
return NULL;
}
void checkThreadPool() {
int running = EM_ASM_INT(return Object.keys(PThread.pthreads).length);
int unused = EM_ASM_INT(return PThread.unusedWorkers.length);
printf("running=%d unused=%d\n", running, unused);
assert(running == 0);
assert(unused == 1);
}
int main() {
printf("in main\n");
checkThreadPool();
pthread_t t, t2;
for (int i = 0; i < 3; i++) {
ready = 0;
// Create a thread that exit's with a non-zero keepalive counter
pthread_create(&t, NULL, thread_main, (void*)1);
while (!ready) {}
pthread_cancel(t);
pthread_join(t, NULL);
checkThreadPool();
// Create a second thread that should re-use the same worker.
// This thread should reset its keepalive counter on startup and
// be able to exit normally.
pthread_create(&t2, NULL, thread_main, NULL);
pthread_join(t2, NULL);
checkThreadPool();
}
printf("done\n");
}