C++ TCP Socket Plugin - c++

I am currently working with the simulation engine VBS2 and am attempting to write a TCP socket plugin. I have a client application which I want to connect to the plugin and send a single message. Perhaps this will make more sense if I post the existing plugin code:
#include <windows.h>
#include "VBSPlugin.h"
// Command function declaration
typedef int (WINAPI * ExecuteCommandType)(const char *command, char *result, int resultLength);
// Command function definition
ExecuteCommandType ExecuteCommand = NULL;
// Function that will register the ExecuteCommand function of the engine
VBSPLUGIN_EXPORT void WINAPI RegisterCommandFnc(void *executeCommandFnc)
{
ExecuteCommand = (ExecuteCommandType)executeCommandFnc;
}
// This function will be executed every simulation step (every frame) and took a part in the simulation procedure.
// We can be sure in this function the ExecuteCommand registering was already done.
// deltaT is time in seconds since the last simulation step
VBSPLUGIN_EXPORT void WINAPI OnSimulationStep(float deltaT)
{
//{ Sample code:
ExecuteCommand("0 setOvercast 1", NULL, 0);
//!}
}
// This function will be executed every time the script in the engine calls the script function "pluginFunction"
// We can be sure in this function the ExecuteCommand registering was already done.
// Note that the plugin takes responsibility for allocating and deleting the returned string
VBSPLUGIN_EXPORT const char* WINAPI PluginFunction(const char *input)
{
//{ Sample code:
static const char result[]="[1.0, 3.75]";
return result;
//!}
}
// DllMain
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
OutputDebugString("Called DllMain with DLL_PROCESS_ATTACH\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugString("Called DllMain with DLL_PROCESS_DETACH\n");
break;
case DLL_THREAD_ATTACH:
OutputDebugString("Called DllMain with DLL_THREAD_ATTACH\n");
break;
case DLL_THREAD_DETACH:
OutputDebugString("Called DllMain with DLL_THREAD_DETACH\n");
break;
}
return TRUE;
}
The message sent to the plugin will be used in the OnSimulationStep() function by being passed as an argument to ExecuteCommand(). However, I've also got to be careful about blocking here as the OnSimulationStep() function must be allowed to run every simulation step.
I've been staring at this for a few days now and have tried looking at the winsock tutorials, but I'm not a C++ programmer and am feeling rather stuck. Please would anyone be kind enough to give me a few pointers in the right direction?
Thanks in advance, all advice is greatly appreciated.

I would personally go with boost::asio to save myself all the hassle in dealing with asynchronous IO.
It is relatively straightforward to use, and it works well in the plugin environment - I've done something similar (also in VBS2).

When your plugin must handle data in a short time and you fear that the winsock send function could block, you need to queue the data or write a mechanism that only the important data is written, if this is an option.
One option is a queue in your plugin and a worker thread that pumps the data from the queue to the socket. With the additional thread you can just use a potential blocking call. If the blocking calll is a problem for you, you can set the socket to non-blocking mode and and wait with WSAAsyncSelect for an event indicating that you can write to the peer again.

You could implement an TCP-server which stores incoming messages in an ordered list. In each OnSimulationStep you then query the TCP-server for received messages and apply them to VBS2 via ExecuteCommand.
Remember to use ExecuteCommand always in the thread which calls OnSimulationStep. This means you're not able to execute incoming messages directly in the TCP-server.

Related

libcurl : Handle multiple asynchronous requests in C++

I've been working with easy_perform till now and it worked as expected. But due to timeouts and single threaded application, there's latency in running multiple operations. I'm looking at optimizing these calls by converting them into asynchronous with multi_perform interface, Though I am having hard time understanding correct way to make use of it.
From my understanding, Flow looks something like following :
Create a easy_handle for call
Add this standard easy handle to the multi stack using curl_multi_add_handle
curl_multi_perform : This is where it gets tricky.
As I understand it, This call is happening in a loop.
My application is calling this API to read/write whatever there is to read or write right now etc.
If running_handles is changed from the previous call, there is data to read which we should retrieve using curl_multi_info_read
Clean up when easy handle is processed
curl_multi_remove_handle
curl_easy_cleanup
curl_multi_cleanup
Q:
Does that mean, My application needs to do periodic polling to check if there's data to read?
Is there a way to handle this with callbacks? and the callback method should trigger action in my application in asynchronous way.
Refs I've already reviewed :
Looking at http://www.godpatterns.com/2011/09/asynchronous-non-blocking-curl-multi.html , It says the same thing. Correct me if I'm wrong.
stackoverflow thread and other related : How to do curl_multi_perform() asynchronously in C++?
The prerequisite knowledge needed to understand curl_multi API is Async Sockets.
curl_multi_perform is not a blocking API. As explained in documentation:
When an application has found out there's data available for the multi_handle or a timeout has elapsed, the application should call this function to read/write whatever there is to read or write right now etc. curl_multi_perform returns as soon as the reads/writes are done.
It just needs to be called periodically.
Does that mean, My application needs to do periodic polling to check if there's data to read?
Yes. curl_multi_fdset conveniently extracts the related file descriptors so that you can select on them (select = wait), but you're free to add other descriptors to the same select call, thus interleaving curl work with your own work. Here's an example of how to do it.
Is there a way to handle this with callbacks?
Yes. The transferred data is passed during the curl_multi_perform call into a CURLOPT_WRITEFUNCTION callback. Note: curl_multi_info_read is not for reading data, it's for reading information about the transfer.
for (/* each transfer */) {
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(eh, CURLOPT_WRITEDATA, /* pass userp value */);
curl_multi_add_handle(multi_handle, easy_handle);
}
int still_running;
do {
if (curl_multi_perform(cm, &still_running)) { // will call write_cb() when data is read
/* handle error */ break;
}
if (curl_multi_wait(cm, NULL, 0, 1000, NULL)) {
/* handle error */ break;
}
} while(still_running);
Here's a complete example of using a data callback with multi-transfer: 10-at-a-time.
Note: curl_multi_wait used in this example is a convenience wrapper around a select call.

Wait for data on COM port?

I'm looking for a way to get a Windows serial port to timeout until it has received data. It would be nice if there was some kind of event that triggered or a function to do exactly what I want.
This is my current implementation.
void waitforCom(unsinged char byte)
{
while (true)
{
ClearCommError(serial_handle, &errors, &status);
if (status.cbInQue>0)
{
//check if correct byte
break;
}
}
}
Another API call you could be using is WaitCommEvent().
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363479(v=vs.85).aspx
This call can work asynchronously since it takes an OVERLAPPED object as a parameter. In your case you'd want to simply wait on the EV_RXCHAR event to let you know data has arrived:
OVERLAPPED o = {0};
o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
SetCommMask(comPortHandle, EV_RXCHAR);
if (!WaitCommEvent(comPortHandle, &commEvent, &o))
{
// Check GetLastError for ERROR_IO_PENDING, if I/O is pending then
// use WaitForSingleObject() to determine when `o` is signaled, then check
// the result. If a character arrived then perform your ReadFile.
}
Alternatively you could do the same thing by having a thread with an outstanding ReadFile call, but using the OVERLAPPED object instead of blocking as MSalters recommends.
I'm not really a specialist when it comes to WinApi, but there's a whole article on the Microsoft Developer Network, that covers the subject of serial communications. The article mentions the subject of waiting for the data from a port, and it's supplied with an example.
At the winAPI level, for most applications you need to dedicate a thread to serial port input because ReadFile is a blocking call (but with a timeout). The most useful event you can get is having ReadFile return. Just put ReadFile in a loop in a thread and generate your own event or message to some other thread when ReadFile gets some data.

Why win32 thread doesn't exit automatically?

Background:
In my application written in C++, I create a worker thread which in turn creates two threads using CreateThread(). The two threads which worker thread creates, talk to WCF Service through a client which is implemented using Windows Web Services API which offers C/C++ application programming interface (API) for building SOAP based web services and clients to them. My application implements only the client using this API.
Problem:
The problem I'm facing is that all other threads exit gracefully, except the worker thread, as you can see yourself, in the image below that WorkerThreadProc uses no CPU cycles yet it doesn't exit. There are also few other threads running which are not created by me, but by the runtime.
The thread states are as follows (as reported by ProcessExplorer):
WorkerThreadProc is in Wait:WrUserRequest state.
wWinMainCRTStartup is in Wait:UserRequest state.
All TpCallbackIndependent are in Wait:WrQueue state.
What are they waiting for? What could be possible causes that I need to look into? Also, what is the difference between WrUserRequest and UserRequest? And what does WrQueue mean? I've absolutely no idea what is going on here.
Here is my WorkerThreadProc code. I've removed all the logging statements except the last one at the bottom of the function:
DWORD WINAPI WorkerThreadProc(PVOID pVoid)
{
//Initialize GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Status status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if ( status != Status::Ok )
{
return 1;
}
GuiThreadData *pGuiData = (GuiThreadData*)pVoid;
auto patternIdRequestQueue= new PatternIdRequestQueue();
auto resultQueue = new ResultQueue();
auto patternManager = new PatternManager(patternIdRequestQueue);
LocalScheduler *pScheduler = new LocalScheduler(resultQueue, patternManager);
bool bInitializationDone = pScheduler->Initialize(pGuiData->m_lpCmdLine);
if ( !bInitializationDone )
{
return 0;
}
//PatternIdThread
PatternIdThread patternIdThread(patternIdRequestQueue);
DWORD dwPatternIdThreadId;
HANDLE hPatternIdThread = CreateThread(NULL, 0, PatternIdThreadProc, &patternIdThread, 0, &dwPatternIdThreadId);
ResultPersistence resultPersistence(resultQueue);
DWORD dwResultPersistenceThreadId;
HANDLE hResultPersistenceThread = CreateThread(NULL, 0, ResultPersistenceThreadProc, &resultPersistence, 0, &dwResultPersistenceThreadId);
pScheduler->ScheduleWork(pGuiData->m_hWnd, pGuiData->m_hInstance, ss.str());
pScheduler->WaitTillDone();
patternIdThread.Close();
resultPersistence.Close();
delete pScheduler;
//Uninitialize GDI+
GdiplusShutdown(gdiplusToken);
dwRet = WaitForSingleObject(hPatternIdThread, INFINITE);
CloseHandle(hPatternIdThread);
dwRet = WaitForSingleObject(hResultPersistenceThread,INFINITE);
CloseHandle(hResultPersistenceThread);
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
//IMPORTANT : this verbose message is getting logged!
T_VERBOSE(EvtSrcInsightAnalysis, 0, 0, "After sending message to destroy window");
delete patternManager;
delete patternIdRequestQueue;
delete resultQueue;
return 0;
}
Please see the T_VERBOSE macro, it is used to log verbose message. I see the message is getting logged, yet the thread doesn't exit!
EDIT:
I just commented the following line in my WorkerThreadProc, then worker thread exits gracefully!
SendMessage(pGuiData->m_hWnd, WM_CLOSE, 0, 0);
Does it mean that SendMessage is the culprit? Why would it block the thread the calling thread?
If we look at the docs for SendMessage, you can see this little quote:
To send a message and return immediately, use the SendMessageCallback
or SendNotifyMessage function. To post a message to a thread's message
queue and return immediately, use the PostMessage or PostThreadMessage
function.
and this:
Messages sent between threads are processed only when the receiving
thread executes message retrieval code. The sending thread is blocked
until the receiving thread processes the message. However, the sending
thread will process incoming nonqueued messages while waiting for its
message to be processed. To prevent this, use SendMessageTimeout with
SMTO_BLOCK set. For more information on nonqueued messages, see
Nonqueued Messages.
so from this we can see SendMessage will block till the message is processed, which may somehow lead to a deadlock in your code, as the msgproc doesn't reside in your worker thread, leading to a context switch (which is only triggered when the thread's queue is pumped for messages). Try using PostMessage, which immediately returns.
EDIT: there is also a nice little piece of info here on message deadlocks from SendMessage

WinHTTP Async Callback

I'm not very good in C++, you if you see something in the code fragment which could be better, please educate me!
I'm implementing winhttp in an asynchronous fashion. But im having trouble retrieving the response. I cant figure it out. Because you should be able to parsethe whole response at once. Since multiple concurent request can occur, buffering the response (headers+body) in a global variable is not the way to go.
How can I retrieve the response of the http get request? Or else, is it an good practice to execute winhttp synchronous on a new thread (so the main loop doesn;t get blocked and then calls a function when done?):
void __stdcall cb(HINTERNET h, DWORD_PTR d, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength){
char* s=new char[1];
DWORD dwSize = 0;
if (dwInternetStatus==WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE){
MessageBoxA(0,s,"",0);
WinHttpQueryDataAvailable( h, &dwSize);
.....
}
}
And the call in the main:
...winhttpopen...
WinHttpSetStatusCallback(request, (WINHTTP_STATUS_CALLBACK)whCallback,WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,0);
...winhttpsend....
Check this sample code on MSDN - Asynchronous Completion in WinHTTP.
The call to WinHttpQueryDataAvailable in QueryData generates a status
callback with a WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE completion in
the dwInternetStatus parameter. By checking the value pointed to by
the lpvStatusInformation parameter, the callback can determine how
much data is left to be read, and if there is no remaining data, can
proceed to display all the data that has been read.
This shows you that your callback is called with buffer pointer and length of data in it.

EnterCriticalSection Deadlock

Having what appears to be a dead-lock situation with a multi-threaded logging application.
Little background:
My main application has 4-6 threads running. The main thread responsible for monitoring health of various things I'm doing, updating GUIs, etc... Then I have a transmit thread and a receive thread. The transmit and receive threads talk to physical hardware. I sometimes need to debug the data that the transmit and receive threads are seeing; i.e. print to a console without interrupting them due to their time critical nature of the data. The data, by the way, is on a USB bus.
Due to the threading nature of the application, I want to create a debug console that I can send messages to from my other threads. The debug consule runs as a low priority thread and implements a ring buffer such that when you print to the debug console, the message is quickly stored to a ring buffer and sets and event. The debug console's thread sits WaitingOnSingleObject events from the in bound messages that come in. When an event is detected, console thread updates a GUI display with the message. Simple eh? The printing calls and the console thread use a critical section to control access.
NOTE: I can adjust the ring buffer size if I see that I am dropping messages (at least that's the idea).
In a test application, the console works very well if I call its Print method slowly via mouse clicks. I have a button that I can press to send messages to the console and it works. However, if I put any sort of load (many calls to Print method), everything dead-locks. When I trace the dead-lock, my IDE's debugger traces to EnterCriticalSection and sits there.
NOTE: If I remove the Lock/UnLock calls and just use Enter/LeaveCriticalSection (see the code) I sometimes work but still find myself in a dead-lock situation. To rule out deadlocks to stack push/pops, I call Enter/LeaveCriticalSection directly now but this did not solve my issue.... What's going on here?
Here is one Print statement, that allows me to pass in a simple int to the display console.
void TGDB::Print(int I)
{
//Lock();
EnterCriticalSection(&CS);
if( !SuppressOutput )
{
//swprintf( MsgRec->Msg, L"%d", I);
sprintf( MsgRec->Msg, "%d", I);
MBuffer->PutMsg(MsgRec, 1);
}
SetEvent( m_hEvent );
LeaveCriticalSection(&CS);
//UnLock();
}
// My Lock/UnLock methods
void TGDB::Lock(void)
{
EnterCriticalSection(&CS);
}
bool TGDB::TryLock(void)
{
return( TryEnterCriticalSection(&CS) );
}
void TGDB::UnLock(void)
{
LeaveCriticalSection(&CS);
}
// This is how I implemented Console's thread routines
DWORD WINAPI TGDB::ConsoleThread(PVOID pA)
{
DWORD rVal;
TGDB *g = (TGDB *)pA;
return( g->ProcessMessages() );
}
DWORD TGDB::ProcessMessages()
{
DWORD rVal;
bool brVal;
int MsgCnt;
do
{
rVal = WaitForMultipleObjects(1, &m_hEvent, true, iWaitTime);
switch(rVal)
{
case WAIT_OBJECT_0:
EnterCriticalSection(&CS);
//Lock();
if( KeepRunning )
{
Info->Caption = "Rx";
Info->Refresh();
MsgCnt = MBuffer->GetMsgCount();
for(int i=0; i<MsgCnt; i++)
{
MBuffer->GetMsg( MsgRec, 1);
Log->Lines->Add(MsgRec->Msg);
}
}
brVal = KeepRunning;
ResetEvent( m_hEvent );
LeaveCriticalSection(&CS);
//UnLock();
break;
case WAIT_TIMEOUT:
EnterCriticalSection(&CS);
//Lock();
Info->Caption = "Idle";
Info->Refresh();
brVal = KeepRunning;
ResetEvent( m_hEvent );
LeaveCriticalSection(&CS);
//UnLock();
break;
case WAIT_FAILED:
EnterCriticalSection(&CS);
//Lock();
brVal = false;
Info->Caption = "ERROR";
Info->Refresh();
aLine.sprintf("Console error: [%d]", GetLastError() );
Log->Lines->Add(aLine);
aLine = "";
LeaveCriticalSection(&CS);
//UnLock();
break;
}
}while( brVal );
return( rVal );
}
MyTest1 and MyTest2 are just two test functions that I call in response to a button press. MyTest1 never causes a problem no matter how fast I click the button. MyTest2 dead locks nearly everytime.
// No Dead Lock
void TTest::MyTest1()
{
if(gdb)
{
// else where: gdb = new TGDB;
gdb->Print(++I);
}
}
// Causes a Dead Lock
void TTest::MyTest2()
{
if(gdb)
{
// else where: gdb = new TGDB;
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
gdb->Print(++I);
}
}
UPDATE:
Found a bug in my ring buffer implementation. Under heavy load, when buffer wrapped, I didn't detect a full buffer properly so buffer was not returning. I'm pretty sure that issue is now resolved. Once I fixed the ring buffer issue, performance got much better. However, if I decrease the iWaitTime, my dead lock (or freeze up issue) returns.
So after further tests with a much heavier load it appears my deadlock is not gone. Under super heavy load I continue to deadlock or at least my app freezes up but no where near it use to since I fixed ring buffer problem. If I double the number of Print calls in MyTest2 I easily can lock up every time....
Also, my updated code is reflected above. I know make sure my Set & Reset event calls are inside critical section calls.
With those options closed up, I would ask questions about this "Info" object. Is it a window, which window is it parented to, and which thread was it created on?
If Info, or its parent window, was created on the other thread, then the following situation might occur:
The Console Thread is inside a critical section, processing a message.
The Main thread calls Print() and blocks on a critical section waiting for the Console Thread to release the lock.
The Console thread calls a function on Info (Caption), which results in the system sending a message (WM_SETTEXT) to the window. SendMessage blocks because the target thread is not in a message alertable state (isn't blocked on a call to GetMessage/WaitMessage/MsgWaitForMultipleObjects).
Now you have a deadlock.
This kind of #$(%^ can happen whenever you mix blocking routines with anything that interacts with windows. The only appropriate blocking function to use on a GUI thread is MSGWaitForMultipleObjects otherwise SendMessage calls to windows hosted on the thread can easily deadlock.
Avoiding this involves two possible approaches:
Never doing any GUI interaction in worker threads. Only use PostMessage to dispatch non blocking UI update commands to the UI thread, OR
Use kernel Event objects + MSGWaitForMultipleObjects (on the GUI thread) to ensure that even when you are blocking on a resource, you are still dispatching messages.
Without knowing where it is deadlocking this code is hard to figure out. Two comments tho:
Given that this is c++, you should be using an Auto object to perform the lock and unlock. Just in case it ever becomes non catastrophic for Log to throw an exception.
You are resetting the event in response to WAIT_TIMEOUT. This leaves a small window of opportunity for a 2nd Print() call to set the event while the worker thread has returned from WaitForMultiple, but before it has entered the critical section. Which will result in the event being reset when there is actually data pending.
But you do need to debug it and reveal where it "Deadlocks". If one thread IS stuck on EnterCriticalSection, then we can find out why. If neither thread is, then the incomplete printing is just the result of an event getting lost.
I would strongly recommend a lockfree implementation.
Not only will this avoid potential deadlock, but debug instrumentation is one place where you absolutely do not want to take a lock. The impact of formatting debug messages on timing of a multi-threaded application is bad enough... having locks synchronize your parallel code just because you instrumented it makes debugging futile.
What I suggest is an SList-based design (The Win32 API provides an SList implementation, but you can build a thread-safe template easily enough using InterlockedCompareExchange and InterlockedExchange). Each thread will have a pool of buffers. Each buffer will track the thread it came from, after processing the buffer, the log manager will post the buffer back to the source thread's SList for reuse. Threads wishing to write a message will post a buffer to the logger thread. This also prevents any thread from starving other threads of buffers. An event to wake the logger thread when a buffer is placed into the queue completes the design.