mirror of
https://github.com/ossrs/srs.git
synced 2025-02-14 20:31:56 +00:00
ST: Support set context id while thread running. v5.0.72
This commit is contained in:
parent
9525511032
commit
dc20d5ddbc
12 changed files with 96 additions and 15 deletions
7
trunk/3rdparty/st-srs/key.c
vendored
7
trunk/3rdparty/st-srs/key.c
vendored
|
@ -79,7 +79,12 @@ int st_key_getlimit(void)
|
|||
int st_thread_setspecific(int key, void *value)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
|
||||
return st_thread_setspecific2(me, key, value);
|
||||
}
|
||||
|
||||
|
||||
int st_thread_setspecific2(_st_thread_t *me, int key, void *value)
|
||||
{
|
||||
if (key < 0 || key >= key_max) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
|
2
trunk/3rdparty/st-srs/public.h
vendored
2
trunk/3rdparty/st-srs/public.h
vendored
|
@ -156,6 +156,8 @@ extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_uti
|
|||
|
||||
extern st_netfd_t st_open(const char *path, int oflags, mode_t mode);
|
||||
|
||||
extern int st_thread_setspecific2(st_thread_t thread, int key, void *value);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void _st_show_thread_stack(st_thread_t thread, const char *messg);
|
||||
extern void _st_iterate_threads(void);
|
||||
|
|
1
trunk/3rdparty/st-srs/sched.c
vendored
1
trunk/3rdparty/st-srs/sched.c
vendored
|
@ -689,7 +689,6 @@ _st_thread_t *st_thread_self(void)
|
|||
return _ST_CURRENT_THREAD();
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/* ARGSUSED */
|
||||
void _st_show_thread_stack(_st_thread_t *thread, const char *messg)
|
||||
|
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
|
||||
## SRS 5.0 Changelog
|
||||
|
||||
* v5.0, 2022-10-02, ST: Support set context id while thread running. v5.0.72
|
||||
* v5.0, 2022-09-30, RTC: Refine SDP to support GB28181 SSRC spec. v5.0.71
|
||||
* v5.0, 2022-09-30, GB28181: Refine HTTP parser to support SIP. v5.0.70
|
||||
* v5.0, 2022-09-30, Kernel: Support lazy sweeping simple GC. v5.0.69
|
||||
|
|
|
@ -66,7 +66,12 @@ srs_error_t SrsDummyCoroutine::pull()
|
|||
|
||||
const SrsContextId& SrsDummyCoroutine::cid()
|
||||
{
|
||||
return _srs_context->get_id();
|
||||
return cid_;
|
||||
}
|
||||
|
||||
void SrsDummyCoroutine::set_cid(const SrsContextId& cid)
|
||||
{
|
||||
cid_ = cid;
|
||||
}
|
||||
|
||||
SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h)
|
||||
|
@ -114,6 +119,11 @@ const SrsContextId& SrsSTCoroutine::cid()
|
|||
return impl_->cid();
|
||||
}
|
||||
|
||||
void SrsSTCoroutine::set_cid(const SrsContextId& cid)
|
||||
{
|
||||
impl_->set_cid(cid);
|
||||
}
|
||||
|
||||
SrsFastCoroutine::SrsFastCoroutine(string n, ISrsCoroutineHandler* h)
|
||||
{
|
||||
// TODO: FIXME: Reduce duplicated code.
|
||||
|
@ -257,6 +267,12 @@ const SrsContextId& SrsFastCoroutine::cid()
|
|||
return cid_;
|
||||
}
|
||||
|
||||
void SrsFastCoroutine::set_cid(const SrsContextId& cid)
|
||||
{
|
||||
cid_ = cid;
|
||||
srs_context_set_cid_of(trd, cid);
|
||||
}
|
||||
|
||||
srs_error_t SrsFastCoroutine::cycle()
|
||||
{
|
||||
if (_srs_context) {
|
||||
|
|
|
@ -76,13 +76,17 @@ public:
|
|||
// @return a copy of error, which should be freed by user.
|
||||
// NULL if not terminated and user should pull again.
|
||||
virtual srs_error_t pull() = 0;
|
||||
// Get and set the context id of coroutine.
|
||||
virtual const SrsContextId& cid() = 0;
|
||||
virtual void set_cid(const SrsContextId& cid) = 0;
|
||||
};
|
||||
|
||||
// An empty coroutine, user can default to this object before create any real coroutine.
|
||||
// @see https://github.com/ossrs/srs/pull/908
|
||||
class SrsDummyCoroutine : public SrsCoroutine
|
||||
{
|
||||
private:
|
||||
SrsContextId cid_;
|
||||
public:
|
||||
SrsDummyCoroutine();
|
||||
virtual ~SrsDummyCoroutine();
|
||||
|
@ -92,6 +96,7 @@ public:
|
|||
virtual void interrupt();
|
||||
virtual srs_error_t pull();
|
||||
virtual const SrsContextId& cid();
|
||||
virtual void set_cid(const SrsContextId& cid);
|
||||
};
|
||||
|
||||
// A ST-coroutine is a lightweight thread, just like the goroutine.
|
||||
|
@ -138,8 +143,9 @@ public:
|
|||
// @remark Return ERROR_THREAD_TERMINATED when thread terminated normally without error.
|
||||
// @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
|
||||
virtual srs_error_t pull();
|
||||
// Get the context id of thread.
|
||||
// Get and set the context id of thread.
|
||||
virtual const SrsContextId& cid();
|
||||
virtual void set_cid(const SrsContextId& cid);
|
||||
};
|
||||
|
||||
// High performance coroutine.
|
||||
|
@ -180,6 +186,7 @@ public:
|
|||
return srs_error_copy(trd_err);
|
||||
}
|
||||
const SrsContextId& cid();
|
||||
virtual void set_cid(const SrsContextId& cid);
|
||||
private:
|
||||
srs_error_t cycle();
|
||||
static void* pfn(void* arg);
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 71
|
||||
#define VERSION_REVISION 72
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,10 +62,19 @@ const SrsContextId& SrsThreadContext::get_id()
|
|||
}
|
||||
|
||||
const SrsContextId& SrsThreadContext::set_id(const SrsContextId& v)
|
||||
{
|
||||
return srs_context_set_cid_of(srs_thread_self(), v);
|
||||
}
|
||||
|
||||
void SrsThreadContext::clear_cid()
|
||||
{
|
||||
}
|
||||
|
||||
const SrsContextId& srs_context_set_cid_of(srs_thread_t trd, const SrsContextId& v)
|
||||
{
|
||||
++_srs_pps_cids_set->sugar;
|
||||
|
||||
if (!srs_thread_self()) {
|
||||
if (!trd) {
|
||||
_srs_context_default = v;
|
||||
return v;
|
||||
}
|
||||
|
@ -78,16 +87,12 @@ const SrsContextId& SrsThreadContext::set_id(const SrsContextId& v)
|
|||
srs_assert(r0 == 0);
|
||||
}
|
||||
|
||||
int r0 = srs_thread_setspecific(_srs_context_key, cid);
|
||||
int r0 = srs_thread_setspecific2(trd, _srs_context_key, cid);
|
||||
srs_assert(r0 == 0);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void SrsThreadContext::clear_cid()
|
||||
{
|
||||
}
|
||||
|
||||
impl_SrsContextRestore::impl_SrsContextRestore(SrsContextId cid)
|
||||
{
|
||||
cid_ = cid;
|
||||
|
|
|
@ -28,10 +28,13 @@ public:
|
|||
virtual SrsContextId generate_id();
|
||||
virtual const SrsContextId& get_id();
|
||||
virtual const SrsContextId& set_id(const SrsContextId& v);
|
||||
public:
|
||||
private:
|
||||
virtual void clear_cid();
|
||||
};
|
||||
|
||||
// Set the context id of specified thread, not self.
|
||||
extern const SrsContextId& srs_context_set_cid_of(srs_thread_t trd, const SrsContextId& v);
|
||||
|
||||
// The context restore stores the context and restore it when done.
|
||||
// Usage:
|
||||
// SrsContextRestore(_srs_context->get_id());
|
||||
|
|
|
@ -412,6 +412,11 @@ void *srs_thread_getspecific(int key)
|
|||
return st_thread_getspecific(key);
|
||||
}
|
||||
|
||||
int srs_thread_setspecific2(srs_thread_t thread, int key, void* value)
|
||||
{
|
||||
return st_thread_setspecific2((st_thread_t)thread, key, value);
|
||||
}
|
||||
|
||||
int srs_netfd_fileno(srs_netfd_t stfd)
|
||||
{
|
||||
return st_netfd_fileno((st_netfd_t)stfd);
|
||||
|
|
|
@ -74,6 +74,7 @@ extern int srs_mutex_unlock(srs_mutex_t mutex);
|
|||
|
||||
extern int srs_key_create(int* keyp, void (*destructor)(void*));
|
||||
extern int srs_thread_setspecific(int key, void* value);
|
||||
extern int srs_thread_setspecific2(srs_thread_t thread, int key, void* value);
|
||||
extern void* srs_thread_getspecific(int key);
|
||||
|
||||
extern int srs_netfd_fileno(srs_netfd_t stfd);
|
||||
|
|
|
@ -133,7 +133,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
|
||||
if (true) {
|
||||
SrsContextId v = dc.cid();
|
||||
EXPECT_FALSE(v.empty());
|
||||
EXPECT_TRUE(v.empty());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -150,7 +150,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
dc.stop();
|
||||
|
||||
SrsContextId v = dc.cid();
|
||||
EXPECT_FALSE(v.empty());
|
||||
EXPECT_TRUE(v.empty());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -167,7 +167,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
dc.interrupt();
|
||||
|
||||
SrsContextId v = dc.cid();
|
||||
EXPECT_FALSE(v.empty());
|
||||
EXPECT_TRUE(v.empty());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -205,6 +205,8 @@ public:
|
|||
srs_error_t r0 = srs_success;
|
||||
|
||||
srs_cond_signal(running);
|
||||
|
||||
// The cid should be generated if empty.
|
||||
cid = _srs_context->get_id();
|
||||
|
||||
while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) {
|
||||
|
@ -213,6 +215,9 @@ public:
|
|||
|
||||
srs_cond_signal(exited);
|
||||
|
||||
// The cid might be updated.
|
||||
cid = _srs_context->get_id();
|
||||
|
||||
if (err != srs_success) {
|
||||
srs_freep(r0);
|
||||
return err;
|
||||
|
@ -222,6 +227,38 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VOID TEST(AppCoroutineTest, SetCidOfCoroutine)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
MockCoroutineHandler ch;
|
||||
SrsSTCoroutine sc("test", &ch);
|
||||
ch.trd = ≻
|
||||
EXPECT_TRUE(sc.cid().empty());
|
||||
|
||||
// Start coroutine, which will create the cid.
|
||||
HELPER_ASSERT_SUCCESS(sc.start());
|
||||
HELPER_ASSERT_SUCCESS(sc.pull());
|
||||
|
||||
srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_TRUE(!sc.cid().empty());
|
||||
EXPECT_TRUE(!ch.cid.empty());
|
||||
|
||||
// Should be a new cid.
|
||||
SrsContextId cid = _srs_context->generate_id();
|
||||
EXPECT_TRUE(sc.cid().compare(cid) != 0);
|
||||
EXPECT_TRUE(ch.cid.compare(cid) != 0);
|
||||
|
||||
// Set the cid and stop the coroutine.
|
||||
sc.set_cid(cid);
|
||||
sc.stop();
|
||||
|
||||
// Now the cid should be the new one.
|
||||
srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_TRUE(sc.cid().compare(cid) == 0);
|
||||
EXPECT_TRUE(ch.cid.compare(cid) == 0);
|
||||
}
|
||||
|
||||
VOID TEST(AppCoroutineTest, StartStop)
|
||||
{
|
||||
if (true) {
|
||||
|
|
Loading…
Reference in a new issue