1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

Cover more ST Coroutine code

This commit is contained in:
winlin 2019-04-07 14:35:11 +08:00
parent 3d5508e088
commit 1ce040cc2c
3 changed files with 44 additions and 6 deletions

View file

@ -86,7 +86,7 @@ SrsSTCoroutine::SrsSTCoroutine(const string& n, ISrsCoroutineHandler* h, int cid
context = cid;
trd = NULL;
trd_err = srs_success;
started = interrupted = disposed = false;
started = interrupted = disposed = cycle_done = false;
}
SrsSTCoroutine::~SrsSTCoroutine()
@ -153,8 +153,8 @@ void SrsSTCoroutine::stop()
return;
}
// If there's no error occur from worker, try to set to interrupted error.
if (trd_err == srs_success) {
// If there's no error occur from worker, try to set to terminated error.
if (trd_err == srs_success && !cycle_done) {
trd_err = srs_error_new(ERROR_THREAD_TERMINATED, "terminated");
}
@ -163,7 +163,7 @@ void SrsSTCoroutine::stop()
void SrsSTCoroutine::interrupt()
{
if (!started || interrupted) {
if (!started || interrupted || cycle_done) {
return;
}
interrupted = true;
@ -199,6 +199,9 @@ srs_error_t SrsSTCoroutine::cycle()
if (err != srs_success) {
return srs_error_wrap(err, "coroutine cycle");
}
// Set cycle done, no need to interrupt it.
cycle_done = true;
return err;
}

View file

@ -133,6 +133,8 @@ private:
bool started;
bool interrupted;
bool disposed;
// Cycle done, no need to interrupt it.
bool cycle_done;
public:
// Create a thread with name n and handler h.
// @remark User can specify a cid for thread to use, or we will allocate a new one.

View file

@ -87,13 +87,18 @@ public:
SrsSTCoroutine* trd;
srs_error_t err;
srs_cond_t running;
srs_cond_t exited;
int cid;
// Quit without error.
bool quit;
public:
MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0) {
MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0), quit(false) {
running = srs_cond_new();
exited = srs_cond_new();
}
virtual ~MockCoroutineHandler() {
srs_cond_destroy(running);
srs_cond_destroy(exited);
}
public:
virtual srs_error_t cycle() {
@ -102,10 +107,12 @@ public:
srs_cond_signal(running);
cid = _srs_context->get_id();
while ((r0 = trd->pull()) == srs_success && err == srs_success) {
while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) {
srs_usleep(10 * 1000);
}
srs_cond_signal(exited);
if (err != srs_success) {
srs_freep(r0);
return err;
@ -241,6 +248,9 @@ VOID TEST(AppCoroutineTest, Cycle)
// Set cycle to error.
ch.err = srs_error_new(-1, "cycle");
// When thread terminated, thread will get its error.
srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS);
// Override the error by cycle error.
sc.stop();
@ -250,6 +260,29 @@ VOID TEST(AppCoroutineTest, Cycle)
EXPECT_TRUE(-1 == srs_error_code(err));
srs_freep(err);
}
if (true) {
MockCoroutineHandler ch;
SrsSTCoroutine sc("test", &ch);
ch.trd = ≻
EXPECT_TRUE(srs_success == sc.start());
EXPECT_TRUE(srs_success == sc.pull());
// Quit without error.
ch.quit = true;
// Wait for thread to done.
srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS);
// Override the error by cycle error.
sc.stop();
// Should be cycle error.
srs_error_t err = sc.pull();
EXPECT_TRUE(srs_success == err);
srs_freep(err);
}
}
#endif