andre ahmed andre ahmed -4 years ago 131
C++ Question

How to set a timeout in a function that is running in a thread

I'm doing a blocking communication with a server using a client. the function is running in a thread. I would like to set a time out functionality. I'm not using boost or something like that. I'm using windows threading library.

Here is the function that I want to set a time out functionality in it.

bool S3W::IWFSData::WaitForCompletion(unsigned int timeout)
{

if (m_Buffer)
{
while (!m_Buffer.IsEmpty())
{
unsigned int i = 0;
char gfname[255]; // must be changed to SBuffer
char minHeightArr[8], maxHeightArr[8], xArr[8], yArr[8];

m_PingTime += timeout;

if (m_PingTime > PONG_TIMEOUT)
{
m_PingTime = 0;
return false;
}

while (m_Buffer[i] != '\0')
{
gfname[i] = m_Buffer[i];
i++;
}

gfname[i] = '\0';

for (unsigned int j = 0; j < 8; j++)
{
minHeightArr[j] = m_Buffer[i++];
}

for (unsigned int j = 0; j < 8; j++)
{
maxHeightArr[j] = m_Buffer[i++];
}

double minH = *(double*)minHeightArr;
double maxH = *(double*)maxHeightArr;

for (unsigned int j = 0; j < 8; j++)
{
xArr[j] = m_Buffer[i++];
}

for (unsigned int j = 0; j < 8; j++)
{
yArr[j] = m_Buffer[i++];
}

double x = *(double*)xArr;
double y = *(double*)yArr;

OGRFeature *poFeature = OGRFeature::CreateFeature(m_Layer->GetLayerDefn());

if(poFeature)
{
poFeature->SetField("gfname", gfname);
poFeature->SetField("minHeight", minH);
poFeature->SetField("maxHeight", maxH);

OGRPoint point;
point.setX(x);
point.setY(y);

poFeature->SetGeometry(&point);


if (m_Layer->CreateFeature(poFeature) != OGRERR_NONE)
{
std::cout << "error inserting an area" << std::endl;
}
else
{
std::cout << "Created a feature" << std::endl;
}
}

OGRFeature::DestroyFeature(poFeature);

m_Buffer.Cut(0, i);
}
}

return true;
}


There is a thread that is setting the data to the buffer

int S3W::ImplConnection::Thread(void * pData)
{
SNet::SAutoLock lockReader(m_sLock);
// RECEIVE DATA
SNet::SBuffer buffer;
m_data->SrvReceive(buffer);


// Driver code for inserting data into the buffer in blocking communication
SNet::SAutoLock lockWriter(m_sLockWriter);
m_data->SetData("ahmed", strlen("ahmed"));
double minHeight = 10;
double maxHeight = 11;
double x = 4;
double y = 2;
char minHeightArr[sizeof(minHeight)];
memcpy(&minHeightArr, &minHeight, sizeof(minHeight));


char maxHeightArr[sizeof(maxHeight)];
memcpy(&maxHeightArr, &maxHeight, sizeof(maxHeight));


char xArr[sizeof(x)];
memcpy(&xArr, &x, sizeof(x));


char yArr[sizeof(y)];
memcpy(&yArr, &y, sizeof(y));

m_data->SetData(minHeightArr, sizeof(minHeightArr));
m_data->SetData(maxHeightArr, sizeof(maxHeightArr));
m_data->SetData(xArr, sizeof(xArr));
m_data->SetData(yArr, sizeof(yArr));

m_data->WaitForCompletion(1000);


return LOOP_TIME;
}

Answer Source

In general, you should not use threads for these purposes, because when terminating a thread like this, the process and the other threads could be left in an unknown state. Look here for the explanation.

Therefore, consider using procceses instead. Read here about opening processes in c++.

If you do want to use threads, you can exit the thread after the time passed.

Make a loop (as you have) that will break when some time has elapsed.

#include <ctime>

#define NUM_SECONDS_TO_WAIT 5

// outside your loop

std::time_t t1 = std::time(0);

// and in your while loop, each iteration:

std::time_t t2 = std::time(0);
if ((t2 - t1) >= NUM_SECONDS_TO_WAIT) 
{ 
    break; // ...
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download