175 lines
3.4 KiB
C++
Executable File
175 lines
3.4 KiB
C++
Executable File
#include "rtpconfig.h"
|
|
#include "rtpabortdescriptors.h"
|
|
#include "rtperrors.h"
|
|
#include "rtpsocketutilinternal.h"
|
|
#include "rtptimeutilities.h"
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
using namespace jrtplib;
|
|
|
|
#ifdef RTP_SUPPORT_THREAD
|
|
|
|
#include <jthread/jthread.h>
|
|
|
|
using namespace jthread;
|
|
|
|
void checkError(int status)
|
|
{
|
|
if (status >= 0)
|
|
return;
|
|
|
|
cerr << "ERROR: " << RTPGetErrorString(status) << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
class SignalThread : public JThread
|
|
{
|
|
public:
|
|
SignalThread(RTPAbortDescriptors &a, double delay, int sigCount) : m_ad(a), m_delay(delay), m_sigCount(sigCount)
|
|
{
|
|
}
|
|
|
|
~SignalThread()
|
|
{
|
|
while (IsRunning())
|
|
{
|
|
cout << "Waiting for thread to finish" << endl;
|
|
RTPTime::Wait(RTPTime(1.0));
|
|
}
|
|
}
|
|
private:
|
|
void *Thread()
|
|
{
|
|
JThread::ThreadStarted();
|
|
|
|
cout << "Thread started, waiting " << m_delay << " seconds before sending abort signal" << endl;
|
|
RTPTime::Wait(RTPTime(m_delay));
|
|
cout << "Sending " << m_sigCount << " abort signals" << endl;
|
|
for (int i = 0 ; i < m_sigCount ; i++)
|
|
m_ad.SendAbortSignal();
|
|
|
|
cout << "Thread finished" << endl;
|
|
return 0;
|
|
}
|
|
|
|
RTPAbortDescriptors &m_ad;
|
|
const double m_delay;
|
|
const int m_sigCount;
|
|
};
|
|
|
|
void test1()
|
|
{
|
|
RTPAbortDescriptors ad;
|
|
SignalThread st(ad, 5, 1);
|
|
|
|
st.Start();
|
|
checkError(ad.Init());
|
|
|
|
fd_set fdset;
|
|
FD_ZERO(&fdset);
|
|
FD_SET(ad.GetAbortSocket(), &fdset);
|
|
|
|
if (select(FD_SETSIZE, &fdset, 0, 0, 0) < 0)
|
|
{
|
|
cerr << "Error in select" << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
cout << "Checking if select keeps triggering" << endl;
|
|
int count = 0;
|
|
RTPTime start = RTPTime::CurrentTime();
|
|
while (count < 5)
|
|
{
|
|
count++;
|
|
struct timeval tv = { 1, 0 };
|
|
if (select(FD_SETSIZE, &fdset, 0, 0, &tv) < 0)
|
|
{
|
|
cerr << "Error in select" << endl;
|
|
exit(-1);
|
|
}
|
|
}
|
|
RTPTime delay = RTPTime::CurrentTime();
|
|
delay -= start;
|
|
|
|
cout << "Elapsed time is " << delay.GetDouble();
|
|
if (delay.GetDouble() < 1.0)
|
|
cout << ", seems OK" << endl;
|
|
else
|
|
cout << ", TAKES TOO LONG!" << endl;
|
|
}
|
|
|
|
void test2()
|
|
{
|
|
RTPAbortDescriptors ad;
|
|
SignalThread st(ad, 5, 5);
|
|
|
|
st.Start();
|
|
checkError(ad.Init());
|
|
|
|
fd_set fdset;
|
|
FD_ZERO(&fdset);
|
|
FD_SET(ad.GetAbortSocket(), &fdset);
|
|
|
|
if (select(FD_SETSIZE, &fdset, 0, 0, 0) < 0)
|
|
{
|
|
cerr << "Error in select" << endl;
|
|
exit(-1);
|
|
}
|
|
cout << "Reading one signalling byte, should continue immediately since we've sent multiple signals" << endl;
|
|
ad.ReadSignallingByte();
|
|
if (select(FD_SETSIZE, &fdset, 0, 0, 0) < 0)
|
|
{
|
|
cerr << "Error in select" << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
cout << "Clearing abort signals" << endl;
|
|
ad.ClearAbortSignal();
|
|
|
|
cout << "Waiting for signal, should timeout after one second since we've cleared the signal buffers" << endl;
|
|
struct timeval tv = { 1, 0 };
|
|
RTPTime start = RTPTime::CurrentTime();
|
|
if (select(FD_SETSIZE, &fdset, 0, 0, &tv) < 0)
|
|
{
|
|
cerr << "Error in select" << endl;
|
|
exit(-1);
|
|
}
|
|
RTPTime delay = RTPTime::CurrentTime();
|
|
delay -= start;
|
|
|
|
cout << "Elapsed time is " << delay.GetDouble();
|
|
if (delay.GetDouble() < 1.0)
|
|
cout << ", BUFFER NOT CLEARED?" << endl;
|
|
else
|
|
cout << ", seems OK" << endl;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
#ifdef RTP_SOCKETTYPE_WINSOCK
|
|
WSADATA dat;
|
|
WSAStartup(MAKEWORD(2, 2), &dat);
|
|
#endif // RTP_SOCKETTYPE_WINSOCK
|
|
|
|
test1();
|
|
test2();
|
|
|
|
#ifdef RTP_SOCKETTYPE_WINSOCK
|
|
WSACleanup();
|
|
#endif // RTP_SOCKETTYPE_WINSOCK
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
int main(void)
|
|
{
|
|
cerr << "Thread support is needed for this example" << endl;
|
|
return 0;
|
|
}
|
|
|
|
#endif // RTP_SUPPORT_THREAD
|
|
|