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:
parent
3d5508e088
commit
1ce040cc2c
3 changed files with 44 additions and 6 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue