2025-10-10 16:07:00 +08:00

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