SDL_Flip deadlock - c++

In my application, I've got a simple Execute method that runs the application,
greatly simplified, it looks something like this:
App::Execute()
{
Initialize();
SDL_Event event;
While(Running)
{
while(SDL_PollEvent(&event) > 0)
{
HandleEvent(&event);
}
Render();
}
}
and Render() looks like this, again simplified:
App::Render()
{
SDL_FillRect(MainSurface, NULL, 0x000000); // MainSurface is declared inside the class
// mCurrentScreen->Render(MainSurface);
SDL_Flip(MainSurface);
}
Now this works fine when the debugger is attached, but when I just run the executable,
the application freezes, attaching gdb to the process, I can tell the main thread is stuck inside SDL_Flip().
I have managed to narrow this issue down to me launching a separate thread that listens for clients using sockets, as commenting out the start of this second thread, makes it work in all modes!
The thread is started like this inside the class 'Server':
Server::Start()
{
mThread = std::thread([this](){ListenThread(this); });
}
ListenThread does the usual socket setup
getaddrinfo(), socket(), bind(), listen() and finally, the call to the blocking function
accept().
Again, this server, and the rendering and everything, works perfectly when a debugger is attached, it is only when launched "directly" that it hangs (forcing me to KILL the process to stop it).
The Server and App has no common data structures, Server doesn't know anything about App,
the only relation between them two is that App sets a callback function on Server.
mServer->Callback = [this](Command cmd){ this->CommandReceived(); });
Edit(Append): This only occurs on my PC, I have the exact same setup (ubuntu, gcc, sdl version etc the same) on my laptop, and it works fine on my laptop.
Note sure if/how it's relevant, but I'm running Ubuntu inside a Hyper-V virtual machine on Windows 8, if that's any help.

Related

XInputGetState hangs

I'm trying to use XInput API for my game engine (I'm using DirectX11 and C++). I just want to test if a controller is found so I #included and call XInputGetState but I get a strange behavior:
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
DWORD result;
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
{
result = XInputGetState(i, &state);
if (result == ERROR_SUCCESS)
ErrorBox(L"found controller on port ");
}
if I connect a controller the program hangs and freezes, while if I disconnect the controller the game launches. If I step into the code with the debugger the result is that the controller is found and the message box is displayed.
Why?
EDIT the problem seems to be in the call to ErrorBox: this function just displays a Message Box using Win32 API.
There is a performance hit when you check for a controller that wasn't attached last time you called it because it has to enumerate device, open driver connects, etc. Therefore, you are recommended to round-robin calls to check for new controllers. If you get ERROR_DEVICE_NOT_CONNECTED back, you shouldn't call XInputGetState again for that slot for a little while. For an example of this, see GamePad class in the Directx Tool Ki and the ThrottleRetry function.
In other words, the loop you wrote before is not a good idea to call every frame unless there are XUSER_MAX_COUNT controllers actually connected.

How do I (gracefully) terminate a gSOAP server?

I have gSOAP server generated from a WSDL file + a Qt GUI. The generated code works perfectly fine, except one point that causes my process to stay alive after GUI exits. (I'm deploying on Windows, so I have no signaling)
I need my GUI to stay alive (naturally) so I moved server-proxy object to a QObject-based class that the latter is moved to another QThread, and the I fire it up by an external signal. The server now runs on event-loop of its parent QObject and works fine.
The only problem is that I have no clue how to terminate server on exit. I tried tweaking generated code for server (is that really a good idea by the way?)
int MySweetService::run(int port)
{ if (!soap_valid_socket(this->soap->master) && !soap_valid_socket(this->bind(NULL, port, 100)))
return this->soap->error;
for (;;) // =====> Maybe here I can put my while(module_is_running_atomic_bool) ?
{ if (!soap_valid_socket(this->accept()))
{ if (this->soap->errnum == 0) // timeout?
this->soap->error = SOAP_OK;
break;
}
if (this->serve())
break;
this->destroy();
}
return this->soap->error;
}
Calling soap_done(&soap) from another thread terminates blocking call to accept() and next your "serving" thread. It works for me on Windows but I doesn't on Linux - it looks like gsoap has some multitasking issue. You also need some boolean flag to let "serving" thread know that you shut it down and it's not just error in gsope.

Qt avoid warning QProcess: destroyed while process still running (Assistant)

I am running a Qt app that launches a process. (The Assistant, launched from the main app).
When I close the app, I get the warning
QProcess: Destroyed while process is still running.
How can I get rid of it ?
I saw this similar question and tried to kill... Nothing happened.
This question seems to say maybe I should add waitForFinished()... Help won't close when app does.
Help::Help():m_helpProcess(0) {}
Help::~Help()
{
if (m_helpProcess) {
m_helpProcess.waitForFinished(); // help stays open after app closes
m_helpProcess->kill(); // added with no effect
delete m_helpProcess;
}
}
bool Help::start()
{
if (!m_helpProcess)
process = new QProcess();
QStringList args;
args << QLatin1String("-collectionFile")
<< QLatin1String("mycollection.qhc");
process->start(QLatin1String("Assistant.app"), args);
if (!process->waitForStarted())
return;
}
It should be sufficient to rewrite the destructor using close():
Closes all communication with the process and kills it. After calling this function, QProcess will no longer emit readyRead(), and data can no longer be read or written.
Help::~Help()
{
if (m_helpProcess) {
// m_helpProcess->waitForFinished(); // help stays open after app closes
m_helpProcess->close(); // close channels
delete m_helpProcess; // destructor actually kills the process
}
}

Why message loop doesn't block the GUI in windows app but does in Qt?

I'm working on a program using Qt, and some of my code is based on Windows samples. The problem I'm having, and something I don't quite understand is how the same code will block my Qt GUI while it will work totally fine in a windows app.
Here's an example. I have a program which gets some data from the camera, does some processing on it, then displays it on the screen. In Windows sample there's something like this:
// Create an event with these self-explanatory parameters
// This event signals when the next frame is ready to process
HANDLE frameEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)
// Now run a while loop which magically doesn't block
HANDLE hEvents[1];
while (WM_QUIT != msg.message)
{
hEvents[0] = frameEvent;
DWORD dwEvent = MsgWaitForMultipleObjects(1, hEvents, FALSE, INFINITE, QS_ALLINPUT);
// If we have our event run some processing
if (WAIT_OBJECT_0 == dwEvent)
{
update();
}
// Else handle input or whatever
}
The update function looks something like this:
if (WAIT_OBJECT_0 = WaitForSingleObject(frameEvent, 0)
{
getTheFrame();
processTheFrame();
drawTheFrame();
}
If I try to implement it the same way in Qt everything will freeze and the while loop will just run forever. The solution I've got is to run the loop in separate thread (QThread) and emit a signal when new frame is ready, like this:
void Worker::run()
{
running_ = true;
while (running_)
{
if (WaitForSingleObject(frameEvent, 0) == WAIT_OBJECT_0)
{
emit signalFrame();
}
// This is necessary or it will still freeze!
usleep(15);
}
}
The signal is then connected to a slot which does similar job to the Update() method from the windows sample.
Now, this works fine, but only as long as processing a single frame can be done before the next frame is available.
As my processing went more complex and is slower then camera framerate, the program just stops responding. The exact same code in the windows sample still works fine, the framerate just drops, but everything is drawn and the GUI remains responsive.
Could someone explain what is going on, and what may be a possible solution?
The Win32 version calls MsgWaitForMultipleObjects. As its name should imply, it waits for either the specified objects to be signaled or for a window message (and since it's called with QS_ALLINPUT, any window message). Presumably the code also dispatches the window message afterward.
Your version calls WaitForSingleObject. As its name should imply, it waits on only the specified object. It won't unblock itself on window messages.

Indy10 TCP Server Freezing

I using Indy with C++ Builder XE3. It's perfect system but i have some problems. IdTCPServer works really good but when i have some connections on him and i want to stop server then my application freezed. I try to tell how i do it step by step:
1) Starting application (and server listening)
2) wait for new connections (or simulate it, no difference)
3) when we have 10-15 connections - then try to stop server listening.
4) when code came to IdTCPServer1->Active = false - application will be frozen
i made little video. Maybe it explain situation much better. http://www.youtube.com/watch?v=BNgTxYbLx8g
And here my code:
OnConnect:
EnterCriticalSection(&CritLock);
++ActiveConnections;
SetActiveConnections(ActiveConnections);
LeaveCriticalSection(&CritLock);
OnDisconnect:
EnterCriticalSection(&CritLock);
--ActiveConnections;
SetActiveConnections(ActiveConnections);
LeaveCriticalSection(&CritLock);
StopServer Code:
void TForm1::StopServer()
{
TList *list = IdTCPServer1->Contexts->LockList();
try
{
for(int i = 0; i < list->Count; ++i)
{
TIdContext *AContext = reinterpret_cast<TIdContext*>(list->Items[i]);
try
{
if (AContext->Connection->Connected())
{
AContext->Connection->IOHandler->InputBuffer->Clear();
AContext->Connection->IOHandler->WriteBufferCancel();
AContext->Connection->IOHandler->WriteBufferClear();
AContext->Connection->IOHandler->WriteBufferClose();
AContext->Connection->IOHandler->CloseGracefully();
AContext->Connection->Disconnect();
}
}
catch (const Exception &e)
{
}
}
}
__finally
{
IdTCPServer1->Contexts->UnlockList();
}
IdTCPServer1->Contexts->Clear();
//IdTCPServer1->StopListening();
IdTCPServer1->Active = false;
}
Thanks for advise!
You need to get rid of all your StopServer() code except for the very last line. When TIdTCPServer is deactivated, it performs all necessary cleanups for you. DO NOT DO IT YOURSELF (especially since you are doing it wrong anyway).
void TForm1::StopServer()
{
IdTCPServer1->Active = false;
}
Now, with just that code, if your app is still freezing, then that means you are deadlocking the main thread. That happens if you call StopServer() in the context of the main thread and one of two things are happening in your server code:
one of your TIdTCPServer event handlers performs a synchronized operation to the main thread (either via TIdSync or TThread::Synchronize()).
one of your TIdTCPServer event handlers swallows Indy exceptions and does not allow TIdTCPServer to terminate one or more client threads correctly when needed.
Internally, the TIdTCPServer::Active property setter closes all active sockets and waits for their respective threads to fully terminate, blocking the calling thread until the property setter exits. If yoou are deactivating the server in the main thread and one of the server threads performs a sync that the main thread cannot process, or otherwise does not terminate correctly when it should be, that will block the server deactivation from exiting and thus deadlock the main thread.
So make sure that:
you are not performing sync operations to the main thread while the server is being deactivated by the main thread. If you must sync, then deactivate the server in a worker thread instead so the main thread is not blocked anymore.
your event handlers are not swallowing any Indy EIdException-derived exceptions in try/catch blocks. If you catch such an exception, re-throw it when you are finshed using it. Let TIdTCPServer handle any Indy exceptions so it can perform internal cleanups as needed.
Lastly, on a side note, you do not need to keep track of connections manually. TIdTCPServer already does that for you in the Contexts property. If you need to know how many clients are currently connected at any moment, simply Lock() the Contexts list, read its Count property (or do anything else you need to do with the clients), and then Unlock() the list.