-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
Description
Version of emscripten/emsdk:
3.1.46
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().
Metadata
Metadata
Assignees
Labels
No labels