mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
parent
27083430ce
commit
df7faa1603
1 changed files with 89 additions and 22 deletions
|
@ -69,28 +69,19 @@ class MockTcpHandler : public ISrsTcpHandler
|
|||
private:
|
||||
srs_netfd_t fd;
|
||||
public:
|
||||
MockTcpHandler();
|
||||
virtual ~MockTcpHandler();
|
||||
MockTcpHandler() {
|
||||
fd = NULL;
|
||||
}
|
||||
virtual ~MockTcpHandler() {
|
||||
srs_close_stfd(fd);
|
||||
}
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd) {
|
||||
fd = stfd;
|
||||
return srs_success;
|
||||
}
|
||||
};
|
||||
|
||||
MockTcpHandler::MockTcpHandler()
|
||||
{
|
||||
fd = NULL;
|
||||
}
|
||||
|
||||
MockTcpHandler::~MockTcpHandler()
|
||||
{
|
||||
srs_close_stfd(fd);
|
||||
}
|
||||
|
||||
srs_error_t MockTcpHandler::on_tcp_client(srs_netfd_t stfd)
|
||||
{
|
||||
fd = stfd;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
VOID TEST(TCPServerTest, PingPong)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
@ -1459,7 +1450,7 @@ public:
|
|||
int r0;
|
||||
int r1;
|
||||
SrsFastCoroutine trd;
|
||||
MockStopSelfThread() : trd("mock", this), r0(0), r1(0) {
|
||||
MockStopSelfThread() : r0(0), r1(0), trd("mock", this) {
|
||||
}
|
||||
virtual ~MockStopSelfThread() {
|
||||
}
|
||||
|
@ -1476,12 +1467,88 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VOID TEST(StopSelfThreadTest, ShouldFailWhenStopSelf)
|
||||
VOID TEST(ThreadCriticalTest, ShouldFailWhenStopSelf)
|
||||
{
|
||||
srs_error_t err;
|
||||
MockStopSelfThread trd;
|
||||
trd.start();
|
||||
HELPER_EXPECT_SUCCESS(trd.start());
|
||||
|
||||
// Switch to thread cycle, should fail.
|
||||
srs_usleep(0);
|
||||
EXPECT_EQ(-1, trd.r0);
|
||||
EXPECT_EQ(EDEADLK, trd.r1);
|
||||
}
|
||||
|
||||
class MockAsyncReaderThread : public ISrsCoroutineHandler
|
||||
{
|
||||
public:
|
||||
SrsFastCoroutine trd;
|
||||
srs_netfd_t fd;
|
||||
MockAsyncReaderThread(srs_netfd_t v) : trd("mock", this), fd(v) {
|
||||
}
|
||||
virtual ~MockAsyncReaderThread() {
|
||||
}
|
||||
srs_error_t start() {
|
||||
return trd.start();
|
||||
}
|
||||
void stop() {
|
||||
trd.stop();
|
||||
}
|
||||
virtual srs_error_t cycle() {
|
||||
srs_error_t err = srs_success;
|
||||
while (true) {
|
||||
if ((err = trd.pull()) != srs_success) {
|
||||
return err;
|
||||
}
|
||||
char buf[16] = {0};
|
||||
if (st_read((st_netfd_t)fd, buf, sizeof(buf), SRS_UTIME_NO_TIMEOUT) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
VOID TEST(ThreadCriticalTest, FailIfCloseActiveFD)
|
||||
{
|
||||
srs_error_t err;
|
||||
|
||||
MockTcpHandler h;
|
||||
SrsTcpListener l(&h, _srs_tmp_host, _srs_tmp_port);
|
||||
HELPER_EXPECT_SUCCESS(l.listen());
|
||||
|
||||
SrsTcpClient c0(_srs_tmp_host, _srs_tmp_port, _srs_tmp_timeout);
|
||||
HELPER_EXPECT_SUCCESS(c0.connect());
|
||||
|
||||
srs_usleep(30 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_TRUE(h.fd != NULL);
|
||||
|
||||
MockAsyncReaderThread trd0(h.fd);
|
||||
HELPER_EXPECT_SUCCESS(trd0.start());
|
||||
|
||||
MockAsyncReaderThread trd1(h.fd);
|
||||
HELPER_EXPECT_SUCCESS(trd1.start());
|
||||
|
||||
// Wait for all threads to run.
|
||||
srs_usleep(10 * SRS_UTIME_MILLISECONDS);
|
||||
|
||||
// Should fail when close, because there is 2 threads reading fd.
|
||||
int r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(-1, r0);
|
||||
EXPECT_EQ(EBUSY, errno);
|
||||
|
||||
// Stop thread1, still fail because thread0 is reading fd.
|
||||
trd1.stop();
|
||||
r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(-1, r0);
|
||||
EXPECT_EQ(EBUSY, errno);
|
||||
|
||||
// Stop thread0, should success, no threads is reading fd.
|
||||
trd0.stop();
|
||||
r0 = st_netfd_close((st_netfd_t)h.fd);
|
||||
EXPECT_EQ(0, r0);
|
||||
|
||||
// Set fd to NULL to avoid close fail for EBADF.
|
||||
h.fd = NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue