Version of emscripten/emsdk:
Failing command line in full:
The script will build and run the page, refreshing until the thread fails to start for some time. Due to the namespace-level object, it is random whether runThread() runs successfully. When it breaks, it seems to deadlock when attempting to execute the cout line.
#!/bin/sh
set -e
set -v
cat << EOF > mywrapper.cpp
#include <atomic>
#include <memory>
#include <thread>
class MyWrapper
{
public:
explicit MyWrapper();
~MyWrapper();
bool isThreadReady() const;
private:
void runThread();
std::unique_ptr<std::thread> m_ThreadPtr;
std::atomic_bool m_IsThreadReady;
};
#include <emscripten/bind.h>
#include <iostream>
struct StaticInitStruct
{
StaticInitStruct() : m_thread_id(0)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 1024 * 1024);
const int thread_created = pthread_create(&m_thread_id, &attr, _start, this);
pthread_attr_destroy(&attr);
}
static void* _start(void* context)
{
std::cout << "STARTED\n";
return nullptr;
}
pthread_t m_thread_id;
};
int i1;
std::string s1;
std::string s2;
int i2;
std::string s3;
std::string s4;
unsigned int s5;
StaticInitStruct statInit;
int main(int argc, char** argv)
{
return 0;
}
MyWrapper::MyWrapper() :
m_IsThreadReady(false)
{
m_ThreadPtr.reset(
new std::thread(&MyWrapper::runThread, this));
}
MyWrapper::~MyWrapper()
{
if (m_ThreadPtr)
{
m_ThreadPtr->join();
m_ThreadPtr.reset();
}
}
void MyWrapper::runThread()
{
std::cout << "runThread\n";
m_IsThreadReady.store(true);
}
bool MyWrapper::isThreadReady() const
{
return m_IsThreadReady.load();
}
// clang-format off
EMSCRIPTEN_BINDINGS(my_wrapper)
{
emscripten::class_<MyWrapper>("MyWrapper")
.constructor()
.function("isThreadReady", &MyWrapper::isThreadReady)
;
}
// clang-format on
EOF
cat << EOF > index.html
<head>
<script type='text/javascript' src=./myWrapperModule.js />
</head>
<body>
<script>
console.log("Get started");
</script>
<script>
MyWrapperModule().then(module => {
var wrapper = new module.MyWrapper();
var refreshPageNow = false;
setTimeout(() => {
refreshPageNow = true;
}, 1750);
var threadCheckInterval = setInterval(() => {
if (wrapper.isThreadReady())
{
console.trace("READY");
clearInterval(threadCheckInterval);
location.reload();
} else if (refreshPageNow) {
console.log("BROKEN");
clearInterval(threadCheckInterval);
document.getElementById("result").innerHTML = "BROKEN";
} else {
console.log("WAIT");
}
}, 500);
});
</script>
<p>TESTING</p>
<p id="result"></p>
</body>
EOF
cat << EOF > pre.js
Module['mainScriptUrlOrBlob'] = self.location.origin + '/myWrapperModule.js';
EOF
em++ -sUSE_PTHREADS -fwasm-exceptions -O2 -g -o mywrapper.cpp.o -c mywrapper.cpp
em++ -sUSE_PTHREADS -fwasm-exceptions -O2 -g -sWASM=1 \
-sPROXY_TO_PTHREAD -sINITIAL_MEMORY=128MB -sPTHREAD_POOL_SIZE=1 -sMODULARIZE=1 \
-sEXPORT_NAME=MyWrapperModule --pre-js=pre.js --minify=0 --bind \
-sENVIRONMENT=web,worker mywrapper.cpp.o -o myWrapperModule.js
emrun index.html
This likely can't be made to work, so it should maybe be documented, diagnosed and possibly fail-early if pthread_create is called before main().
Version of emscripten/emsdk:
Failing command line in full:
The script will build and run the page, refreshing until the thread fails to start for some time. Due to the namespace-level object, it is random whether
runThread()runs successfully. When it breaks, it seems to deadlock when attempting to execute thecoutline.This likely can't be made to work, so it should maybe be documented, diagnosed and possibly fail-early if pthread_create is called before
main().