I'm working on project to attach video from c++.
I have success create video element from c++.
video = emscripten::val::global("document").call<emscripten::val>("createElement", emscripten::val("video"));
video.set("src", emscripten::val("http://jplayer.org/video/webm/Big_Buck_Bunny_Trailer.webm"));
video.set("crossOrigin", emscripten::val("Anonymous"));
video.set("autoplay", emscripten::val(true));
video.call<void>("load");
But the problem came up is I have to wait until video buffer load enough to play.
My solution is using pthread to create thread wait until video buffer load enough and do stuff with the video.
pthread_create(&threadVideo, NULL, attachVideo, NULL);
And inside attachVideo function
void *attachVideo(void *arg)
{
pthread_detach(pthread_self());
cout << "ready to run" << endl;
cout << "readyState: " << video["readyState"].as<int>() << endl;
pthread_exit(NULL);
}
And when I run it cameout error: Cannot read properties of undefined (reading 'value')"
Can someone help me with this ?
This is because emscripten::val is represents an object in JS and the JS state is all thread local. Another way of putting it: Each thread gets is own JS environment, so emscripten::val cannot be shared between threads.
Related
I am writing a simple Qt C++ GUI window for the user to input certain values for a USRP device to record (i.e. input start frequency, stop frequency, etc..). Once the user inputted the values, the "EXECUTE" button is clicked and the execute_run_usrp() function is called in its own thread (so not to block the GUI). Then the STOP button should be able to be clicked at any time to terminate the thread running the function that runs the USRP, execute_run_usrp(), thus terminating the USRP recording process.
The function run_usrp(x,y,z,etc) is defined in another *.cpp file in the Project.
The problem that I am having that the STOP button when clicked only seems to "pause" the function...doesn't actually kill it (like with CTRL-C, which works great here)
Here is my code from MainWindow.cpp for the EXECUTE button click:
// run the following when EXECUTE button is clicked
void MainWindow::on_button_EXECUTE_clicked()
{
if ( ui->calculated_StartTime->text() == "" )
{
QMessageBox messageBox;
messageBox.critical(0,"Error","Hit the \"CALCULATE SCHEDULE\" button first above!!");
messageBox.setFixedSize(500,200);
return;
}
ui->button_STOP->setVisible(true);
ui->button_EXECUTE->setVisible(false);
auto function = std::bind([this]{execute_run_usrp();});
QThread* temp = QThread::create(function);
temp->start();
connect( ui->button_STOP, SIGNAL(clicked()), temp, SLOT( terminate() ));
}
Here is the execute_run_usrp() function:
void MainWindow::execute_run_usrp()
{
float startFreq = ui->input_startFreq->text().toFloat();
float stopFreq = ui->input_stopFreq->text().toFloat();
float stepFreq = ui->input_stepFreq->text().toFloat();
int nRepeats = ui->input_numRepeats->text().toInt();
float ipp = ui->input_IPP->text().toFloat();
int sweepCadence = ui->calculated_sweepCadence->text().toInt();
int numSweeps = ui->input_numSweeps->text().toInt();
std::string schedule_run = ui->calculated_StartTime->text().toStdString();
std::cout << startFreq << std::endl;
std::cout << stopFreq << std::endl;
std::cout << stepFreq<< std::endl;
std::cout << nRepeats << std::endl;
std::cout << ipp << std::endl;
std::cout << sweepCadence << std::endl;
std::cout << numSweeps << std::endl;
run_usrp(startFreq, stopFreq, stepFreq, nRepeats, ipp, sweepCadence, numSweeps, schedule_run);
}
And here is the STOP button code:
void MainWindow::on_button_STOP_clicked()
{
ui->button_STOP->setVisible(false);
ui->button_EXECUTE->setVisible(true);
}
Clicking the STOP button only seems to pause the function, doesn't actually kill it like doing CTRL-C with the keyboard. I think the UHD library (that runs the USRPs) spwans its own thread for running.
Question: How do I 100% terminate the entire function (and including any spwaned children from UHD) when I hit the STOP button ?
Thank you very much!
How do I 100% terminate the entire function (and including any spwaned children from UHD) when I hit the STOP button ?
From the code you've shown there's no easy answer imho.
The shortest one is: by incorporating some inter-thread communication inside the USRP function, provided you want some sort of graceful exit.
As for terminate, QT's docs state:
This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Alternatively, the whole USRP function can be run inside a separate process, that is then killed. Again, plain killing of the process is far from graceful, still it seems easier and safer than doing it to a thread. You may want to check QProcess for reference.
Follow-up for this question.
I'm trying to create a NodeJS native addon that uses OpenGL.
I'm not able to use OpenGL functions because CGLGetCurrentContext() always returns NULL.
When trying to create a new context to draw into, CGLChoosePixelFormat always returns the error kCGLBadConnection invalid CoreGraphics connection.
What is bugging me out is that when I isolate the code that creates the OpenGL context into a standalone CPP project, it works! It just gives an error when I run it inside the NodeJS addon!
I created this NodeJS native addon project to exemplify my error: https://github.com/Psidium/node-opengl-context-error-example
This is the code that works when executed on a standalone project and errors out when running inside NodeJS:
//
// main.cpp
// test_cli
//
// Created by Borges, Gabriel on 4/3/20.
// Copyright © 2020 Psidium. All rights reserved.
//
#include <iostream>
#include <OpenGL/OpenGL.h>
int main(int argc, const char * argv[]) {
std::cout << "Context before creating it: " << CGLGetCurrentContext() << "\n";
CGLContextObj context;
CGLPixelFormatAttribute attributes[2] = {
kCGLPFAAccelerated, // no software rendering
(CGLPixelFormatAttribute) 0
};
CGLPixelFormatObj pix;
CGLError errorCode;
GLint num; // stores the number of possible pixel formats
errorCode = CGLChoosePixelFormat( attributes, &pix, &num );
if (errorCode > 0) {
std::cout << ": Error returned by choosePixelFormat: " << errorCode << "\n";
return 10;
}
errorCode = CGLCreateContext( pix, NULL, &context );
if (errorCode > 0) {
std::cout << ": Error returned by CGLCreateContext: " << errorCode << "\n";
return 10 ;
}
CGLDestroyPixelFormat( pix );
errorCode = CGLSetCurrentContext( context );
if (errorCode > 0) {
std::cout << "Error returned by CGLSetCurrentContext: " << errorCode << "\n";
return 10;
}
std::cout << "Context after being created is: " << CGLGetCurrentContext() << "\n";
return 0;
}
I already tried:
Using fork() to create a context in a subprocess (didn't work);
Changing the pixelformat attributes to something that will create my context (didn't work);
I have a hunch that it may have something to do with the fact that a Node native addon is a dynamically linked library, or maybe my OpenGL createContext function may not be executing on the main thread (but if this was the case, the fork() would have solved it, right?).
Accessing graphics hardware requires extra permissions - Windows and macOS (don't know for others) restrict creation of hardware-accelerated OpenGL context to interactive user session (I may be wrong with the terms here). From one of articles on the web:
In case the user is not logged in, the CGLChoosePixelFormat will return kCGLBadConnection
Interactive session is easier to feel than to understand; e.g. when you interactively login and launch application - it is interactive session; when process is started as service - it is non-interactive. How this is actually managed by system requires deeper reading. As far as I know, there is no easy way "escaping" non-interactive process flag.
NodeJS can be used as part of a web-server, so that I may expect that it can be exactly the problem - it is started as a service, by another non-interactive user or has other special conditions making it non-interactive. So maybe more details on how you use / start NodeJS itself might clarify why the code doesn't work. But I may expect that using OpenGL on server part might be not a good idea anyway (if this is a target); although it might be possible that software OpenGL implementation (without kCGLPFAAccelerated flag might work).
By the way, there are at least two OpenGL / WebGL extensions to NodeJS - have you tried their samples to see if they behave in the same or different way in your environment?
https://github.com/google/node-gles
https://github.com/mikeseven/node-webgl
I'm using QtConcurrent::run to execute some functions in background and not hang the GUI thread. In one function, I read logs from local SQlite database and send them to server by TCP socket.
Now I want to delay the execution after each log so the server has time to save it (TCP response is read in different thread). I'm stuck with Qt4.8 due to implementation limitations (many embeded devices - no chance to upgrade QT on them) and I can't use QThread::sleep(2) because it is protected in 4.8.
Is it possible to somehow pause the execution of thread inside QtConcurrent::run method or should I redesign it to implement my own class inheriting QThread?
void MainWindow::ReportFinishedHUs(bool asyncWork)
{
if(asyncWork == false)
{
QMutexLocker locker(&localDBmutex);
QList<QSqlRecord> HUsToReport = localDB->getHUsForBook();
qDebug() << "HUs to report" << HUsToReport.count();
if(!HUsToReport.isEmpty())
{
Cls_log::WriteDebugLog("HUs to report: " + QString::number(HUsToReport.count()));
foreach (QSqlRecord record, HUsToReport)
{
int _hu = record.indexOf("hu");
int _logTime = record.indexOf("logTime");
QString logTimeString = record.value(_logTime).toString();
QString hu = record.value(_hu).toString();
qDebug() << hu << logTimeString;
// creating message here ...
qDebug() << message;
emit sig_SendTCPMessage(message);
// this is where I need to wait for 2 seconds
QThread::sleep(2);
}
}
}
else
{
QtConcurrent::run(this, &MainWindow::ReportFinishedHUs, false);
}
}
EDIT:
Solved by usleep(2000000) which I somehow discarded for being platform specific... but hey, half of my aplication is platform specific and I only use it in embeded device with constant OS.
Keeping the question open if anyone can suggest more elegand solution using Qt methods. I like to get inspired.
I am currently learning C++ and I am having an odd issue with threads. I've done lots of threaded stuff in Java and C# and not had an issue. I am currently trying to replicate a C# library that I have in C++ with a library and a test app.
In main.cpp I create an instance of a InitialiseLibrary class and call the method initialise. This does config loading and is then supposed to start a thread which stays running through the duration the application is running. I am expecting this thread to start, and then my initialise function returns true where I then continue and I create an instance of a test class which writes to a log file every 1 second.
Below is main.cpp
InitialiseLibrary initLibrary("config.ini");
if (!initLibrary.initialise(1))
{
cout << "Failed to initialise library" << endl;
return EXIT_FAILURE;
}
TestClass testClass;
testClass.writeSomeLogsInThread();
cout << "The library config log file is: " << GlobalConfig::GeneralConfig::logFile << endl;
In my Initialise method (which is in the library) I have:
bool InitialiseLibrary::initialise(int applicationAlarmID, int applicationTerminationTimeout)
{
//statusManager.setApplicationStatus(StatusManager::ApplicationStatus::Starting);
if (!this->loadInconfiguration(applicationAlarmID))
{
cout << "*****Failed to configuration. Cannot continue******" << endl;
return false;
}
GlobalConfig::libraryInitialised = true;
LogRotation logRotation;
logRotation.startLogRotation();
BitsLibrary bitsLibrary;
//Set up the signal handler if its needed, 0 means it terminates instantly, doesn't wait -1 is don't use signal handler
if (applicationTerminationTimeout >= 0)
{
bitsLibrary.setupSignalHandler(applicationTerminationTimeout);
}
return true;
}
As you can see, I read in the configuration and I then call `logRotation.startLogRotation().
Where I have the following code:
void LogRotation::startLogRotation()
{
//Is the configuration successfully loaded
if (!LogRotateConfiguration::configurationLoaded)
{
throw exception("Log Rotation not initialised");
}
BitsLibrary bitsLibrary;
stringstream logStream;
logStream << "Log rotation thread starting, monitor cycle time is " << LogRotateConfiguration::archiveSleepTimeInSeconds << " second(s)";
bitsLibrary.writeToLog(logStream.str(), "LogRotation", "startLogRotation");
thread logRotationThread(&LogRotation::logRotationThread, this);
logRotationThread.join();
}
void LogRotation::logRotationThread()
{
BitsLibrary bitsLibrary;
while (bitsLibrary.getApplicationStatus() == StatusManager::ApplicationStatus::Starting || bitsLibrary.getApplicationStatus() == StatusManager::ApplicationStatus::Running)
{
bitsLibrary.writeToLog("Running log monitoring");
this_thread::sleep_for(chrono::seconds(LogRotateConfiguration::archiveSleepTimeInSeconds));
}
stringstream logStream;
logStream << "Log rotation archive monitoring stopped. Current application status: " << bitsLibrary.getApplicationStatus();
bitsLibrary.writeToLog(logStream.str(), "LogRotation", "logRotationThread");
}
Here I am expecting, startLogRotation() to start run the method logRotationThread within a thread, the thread starts, and the startLogrotation() method finishes and backs through the stack to the initialise() method where that returns true, back up to main where I can then call my TestClass method within a thread.
For some reason though, the thread starts and keeps logging every few seconds Running log monitoring so I know the thread has started, yet it doesn't seem to return back to the initialise function to return true, so the app gets stuck on that function call and doesn't go any further.
I've read that you need to run join on the thread to keep it in sync with the main thread, otherwise the main thread exits, while the new threads are running and cause a SIGABRT which in deed it does, but having the join there seems to stop the method returning.
join waits for a thread to finish executing, so when you join, startLogRotation won't return until that happens.
Also, the normal rules of scope and lifetime apply to thread objects - logRotationThread will be destroyed when startLogRotation returns.
If the thread is "joinable" at the time of destruction, it's an error.
The simplest solution is probably to have a LogRotation member in InitialiseLibrary and a thread member in LogRotation.
You can then join the thread in LogRotation's destructor.
Your main thread blocks at this line, waiting for the logRotationThread to end.
logRotationThread.join();
Your main thread should go and do whatever work it needs to do after spawning the other thread, then only when it has nothing left to do should it join() the log rotate thread.
"having an odd issue with threads" - welcome to the world of threading!
I think you mis-understand the stack of the thread you create, and how it will interact with the main thread. The created thread's stack starts at the function you tell it to start with - when that function completes, the thread dies (which will then allow your join() to stop blocking)
With regards to your communication between threads, I think you should have a read about mutex's, conditions and semaphores.
From what I can tell,
logRotationThread is a long running thread (it runs for the entire duration of the application). There is no need for the main thread to ever wait (join) on the logRotationThread.
For starters remove logRotationThread.join().
I'm currently trying to create a C++ wrapper for my program to use GStreamer.
So I have created a Class "Audio" with a method "play" that starts a stream. Because of the call to g_main_loop_run inside it, it won't return until the main loop quits.
I dont want that behaviour and thus I'm trying to make an async call to another method within the play method, which would then start the main loop and allow the play method to return.
It currently looks like this:
void play(const char* uri) {
stop();
if (uri) {
g_object_set(G_OBJECT(pipeline), "uri", uri, NULL);
} else {
cout << "Please specify an URI you wish to play" << endl;
return;
}
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
auto handle = async( launch::async, &Audio::playAsync, this, uri);
}
void playAsync(const char* uri) {
cout << "playing async" << endl;
g_main_loop_run(this->getLoop());
}
But the result is that the program is getting unresponsive... the playAsync method is called (its printing the cout), and playback starts and continues to play, but the GUI becomes totally unresponsive and can only be quit by killing the program.
Do you have any help for me?
regards, tagelicht
Async returns future and future must be finished (it waits for the result) when it goes out of scope.
It's exactly the same as using just async(...); as handle goes out of scope just after assigment.