ALSA re-enter to callback during callback execution - c++

My application uses ALSA with callbacks facility to play selected piece of sound. Sometimes it just hangs. I was debugging it hardly 2 days, and finally found that ALSA's callback function invoked while it is executing already. I caught this using:
void MyALSACallback()
{
std::cout << "1"; std::cout.flush();
// ... snd_pcm_writei() call ... //
// ... no any returns ... //
std::cout << "2"; std::cout.flush();
return;
}
The application hangs when i have sequence "11" printed. The "121212..." is on console while application is alive and sound is playing.
How that may happen?

Related

Starting/stopping function using QT GUI buttons

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.

C++ async makes program unresponsive

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.

C++ Function Completing Before Other Function Finishes

I am coding a C++ program to interact with the internet using the C++ REST SDK. I have a main function and a webCommunication function. The code is similar to below:
void webCommunication(data, url)
{
//Communicate with the internet using the http_client
//Print output
}
int main()
{
//Obtain information from user
webCommunication(ans1, ans2);
system("PAUSE");
}
However, it seems that the main function is progressing before the webCommunication function is finished. If I make webCommunication a function type of string and have
cout << webCommunication(ans1, ans2) << endl;
But that still pauses and then prints the data retrieved. Normally, this would be fine, expect I am referring to the returned answer later on in the code. If the webCommunication isn't completed, the application crashes. Is there some kind of wait_until function I can use?
UPDATE: I have tried using a mutex suggested with no success. I also tried starting the function as a thread and then using the .join() with still no success.
If you declare your webCommunications() function as a
pplx::task<void> webCommunications()
{
}
Then you can use ".wait()" when calling the function. It will then wait until the function executes to continue. Looks like this:
pplx::task<void> webCommunications()
{
}
int main()
{
webCommunications().wait();
//Do other stuff
}
I think you are missing a keyword in the descriptions. ASYNCHRONOUS. This is indicating that it returns before finishing. If you need it to be synchronous, you should put a semaphore acquire right after the call and put a release into the callback code.
https://msdn.microsoft.com/en-us/library/jj950081.aspx
Modified code snippet from link above( added lock to callback ) :
// Creates an HTTP request and prints the length of the response stream.
pplx::task<void> HTTPStreamingAsync()
{
http_client client(L"http://www.fourthcoffee.com");
// Make the request and asynchronously process the response.
return client.request(methods::GET).then([](http_response response)
{
// Print the status code.
std::wostringstream ss;
ss << L"Server returned returned status code " << response.status_code() << L'.' << std::endl;
std::wcout << ss.str();
// TODO: Perform actions here reading from the response stream.
auto bodyStream = response.body();
// In this example, we print the length of the response to the console.
ss.str(std::wstring());
ss << L"Content length is " << response.headers().content_length() << L" bytes." << std::endl;
std::wcout << ss.str();
// RELEASE lock/semaphore/etc here.
mutex.unlock()
});
/* Sample output:
Server returned returned status code 200.
Content length is 63803 bytes.
*/
}
Note : Acquire the mutex after the function call to start web processing. Add to the callback code to release the mutex. In this way the main thread locks until the function actually finishes and then continues to 'pause'.
int main()
{
HttpStreamingAsync();
// Acquire lock to wait for complete
mutex.lock();
system("PAUSE");
}

double Gtk::Messadialog before quitting

I'm trying to display a message dialog if the pid of running program is valid, This is my essencial code:
Gtk::Main kit (argc, argv);
Glib::RefPtr<Gtk::Builder> refBuilder = Gtk::Builder::create();
try { refBuilder->add_from_file (UI_PATH); }
catch (const Glib::FileError& ex) {
std::cout << "FileError: " << ex.what() << std::endl;
return 1;
}
catch (const Gtk::BuilderError& ex) {
std::cout << "BuilderError: " << ex.what() << std::endl;
return 1;
}
FormUI * ui = 0;
refBuilder->get_widget_derived ("window1", ui);
if (ui) {
kit.run (*ui);
}
delete ui;
Constructor:
signal_delete_event ().connect (sigc::mem_fun (*this, &FormUI::on_delete_event));
method:
bool FormUI::on_delete_event (GdkEventAny* event) {
if (_pid) {
bool retState;
Gtk::MessageDialog md(*this, Glib::ustring::compose ("<b>%1</b>", _("Warning: youtube-dl in process")), true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
md.set_title (PACKAGE_STRING);
md.set_secondary_text (_("Closing can generate a corrupted file, do you want to continue anyway?"));
if (md.run() == Gtk::RESPONSE_YES) {
kill (_pid, 0);
retState = false;
} else {
retState = true;
}
md.hide ();
return retState;
}
return false;
}
With the above, if pid is valid it displays the messagedialog as expected, but if I hit "yes" (to exit the application) it displays another messagedialog..why?
You said that FormUI is derived from Gtk::Window. Gtk::Window has a virtual method on_delete_event() that is automatically connected to the delete-event signal, no questions asked. Oops, you implemented a virtual method without knowing it! So what you did by calling
signal_delete_event ().connect (sigc::mem_fun (*this, &FormUI::on_delete_event));
was unknowingly connect that signal twice, and because Gtk::Window::on_delete_event() is virtual, both connections go to your own method.
Okay, so why do we still get two dialog boxes? Doesn't returning false mean to close the window? Not really.
delete-event is a GDK event. GDK events always return a boolean value: if the value is false (GDK_EVENT_PROPAGATE), the next signal handler in the signal connection chain is run, and if the return value is true (GDK_EVENT_STOP), no further signal in the signal connection chain is run.
It just so happens that if you don't stop a delete-event from propagating through the signal connection chain, the window is destroyed. So when there was only one handler connected, returning false from that handler would effectively destroy the window.
But now you have two handlers connected. The first one will return false, which causes the second one to run, and you get your second message dialog. When that one returns false, you get your window being destroyed.
Hopefully that should explain this problem. You can solve this by either not calling signal_delete_event().connect() or by changing the method name to something else. Be sure to watch the gtkmm documentation to make sure you aren't accidentally using other virtual methods that are automatically connected to signals (I'm not sure why gtkmm provides these virtual methods; convenience?). And be sure to understand how GDK events work; you'll need to know this if you ever play with GDK events for real (such as handling input in a Gtk::DrawingArea).

C++ How to exit out of a while loop recvfrom()

I'm trying to create a UDP broadcast program to check for local game servers, but I'm having some trouble with the receiving end. Since the amount of servers alive is unknown at all times, you must have a loop that only exits when you stop it. So in this bit of code here:
while(1) // start a while loop
{
if(recvfrom(sd,buff,BUFFSZ,0,(struct sockaddr *)&peer,&psz) < 0) // recvfrom() function call
{
cout << red << "Fatal: Failed to receive data" << white << endl;
return;
}
else
{
cout << green << "Found Server :: " << white;
cout << yellow << inet_ntoa(peer.sin_addr), htons(peer.sin_port);
cout << endl;
}
}
I wish to run this recvfrom() function until I press Ctrl + C. I've tried setting up handlers and such (from related questions), but they're all either too complicated for me, or it's a simple function that just exits the program as a demonstration. Here's my problem:
The program hangs on recvfrom until it receives a connection (my guess), so, there's never a chance for it to specifically wait for input. How can I set up an event that will work into this nicely?
Thanks!
In the CTRL-C handler, set a flag, and use that flag as condition in the while loop.
Oh, and if you're not on a POSIX systems where system-calls can be interrupted by signals, you might want to make the socket non-blocking and use e.g. select (with a small timeout) to poll for data.
Windows have a couple of problems with a scheme like this. The major problem is that functions calls can not be interrupted by the CTRL-C handler. Instead you have to poll if there is anything to receive in the loop, while also checking the "exit loop" flag.
It could be done something like this:
bool ExitRecvLoop = false;
BOOL CtrlHandler(DWORD type)
{
if (type == CTRL_C_EVENT)
{
ExitRecvLoop = true;
return TRUE;
}
return FALSE; // Call next handler
}
// ...
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
while (!ExitRecvLoop)
{
fd_set rs;
FD_ZERO(&rs);
FD_SET(sd, &rs);
timeval timeout = { 0, 1000 }; // One millisecond
if (select(sd + 1, &rs, NULL, NULL, &timeout) < 0)
{
// Handle error
}
else
{
if (FD_ISSET(sd, &rs))
{
// Data to receive, call `recvfrom`
}
}
}
You might have to make the socket non-blocking for this to work (see the ioctlsocket function for how to).
Thread off your recvFrom() loop so that your main thread can wait for user input. When user requests stop, close the fd from the main thread and the recvFrom() will return immediately with an error, so allowing your recvFrom() thread to exit.