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

ST: Support set context id while thread running. v5.0.72

This commit is contained in:
winlin 2022-10-02 10:05:01 +08:00
parent 9525511032
commit dc20d5ddbc
12 changed files with 96 additions and 15 deletions

View file

@ -79,7 +79,12 @@ int st_key_getlimit(void)
int st_thread_setspecific(int key, void *value) int st_thread_setspecific(int key, void *value)
{ {
_st_thread_t *me = _ST_CURRENT_THREAD(); _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) { if (key < 0 || key >= key_max) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;

View file

@ -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 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 #ifdef DEBUG
extern void _st_show_thread_stack(st_thread_t thread, const char *messg); extern void _st_show_thread_stack(st_thread_t thread, const char *messg);
extern void _st_iterate_threads(void); extern void _st_iterate_threads(void);

View file

@ -689,7 +689,6 @@ _st_thread_t *st_thread_self(void)
return _ST_CURRENT_THREAD(); return _ST_CURRENT_THREAD();
} }
#ifdef DEBUG #ifdef DEBUG
/* ARGSUSED */ /* ARGSUSED */
void _st_show_thread_stack(_st_thread_t *thread, const char *messg) void _st_show_thread_stack(_st_thread_t *thread, const char *messg)

View file

@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 5.0 Changelog ## 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, 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, GB28181: Refine HTTP parser to support SIP. v5.0.70
* v5.0, 2022-09-30, Kernel: Support lazy sweeping simple GC. v5.0.69 * v5.0, 2022-09-30, Kernel: Support lazy sweeping simple GC. v5.0.69

View file

@ -66,7 +66,12 @@ srs_error_t SrsDummyCoroutine::pull()
const SrsContextId& SrsDummyCoroutine::cid() 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) SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h)
@ -114,6 +119,11 @@ const SrsContextId& SrsSTCoroutine::cid()
return impl_->cid(); return impl_->cid();
} }
void SrsSTCoroutine::set_cid(const SrsContextId& cid)
{
impl_->set_cid(cid);
}
SrsFastCoroutine::SrsFastCoroutine(string n, ISrsCoroutineHandler* h) SrsFastCoroutine::SrsFastCoroutine(string n, ISrsCoroutineHandler* h)
{ {
// TODO: FIXME: Reduce duplicated code. // TODO: FIXME: Reduce duplicated code.
@ -257,6 +267,12 @@ const SrsContextId& SrsFastCoroutine::cid()
return cid_; return cid_;
} }
void SrsFastCoroutine::set_cid(const SrsContextId& cid)
{
cid_ = cid;
srs_context_set_cid_of(trd, cid);
}
srs_error_t SrsFastCoroutine::cycle() srs_error_t SrsFastCoroutine::cycle()
{ {
if (_srs_context) { if (_srs_context) {

View file

@ -76,13 +76,17 @@ public:
// @return a copy of error, which should be freed by user. // @return a copy of error, which should be freed by user.
// NULL if not terminated and user should pull again. // NULL if not terminated and user should pull again.
virtual srs_error_t pull() = 0; virtual srs_error_t pull() = 0;
// Get and set the context id of coroutine.
virtual const SrsContextId& cid() = 0; 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. // An empty coroutine, user can default to this object before create any real coroutine.
// @see https://github.com/ossrs/srs/pull/908 // @see https://github.com/ossrs/srs/pull/908
class SrsDummyCoroutine : public SrsCoroutine class SrsDummyCoroutine : public SrsCoroutine
{ {
private:
SrsContextId cid_;
public: public:
SrsDummyCoroutine(); SrsDummyCoroutine();
virtual ~SrsDummyCoroutine(); virtual ~SrsDummyCoroutine();
@ -92,6 +96,7 @@ public:
virtual void interrupt(); virtual void interrupt();
virtual srs_error_t pull(); virtual srs_error_t pull();
virtual const SrsContextId& cid(); virtual const SrsContextId& cid();
virtual void set_cid(const SrsContextId& cid);
}; };
// A ST-coroutine is a lightweight thread, just like the goroutine. // 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_TERMINATED when thread terminated normally without error.
// @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted. // @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
virtual srs_error_t pull(); virtual srs_error_t pull();
// Get the context id of thread. // Get and set the context id of thread.
virtual const SrsContextId& cid(); virtual const SrsContextId& cid();
virtual void set_cid(const SrsContextId& cid);
}; };
// High performance coroutine. // High performance coroutine.
@ -180,6 +186,7 @@ public:
return srs_error_copy(trd_err); return srs_error_copy(trd_err);
} }
const SrsContextId& cid(); const SrsContextId& cid();
virtual void set_cid(const SrsContextId& cid);
private: private:
srs_error_t cycle(); srs_error_t cycle();
static void* pfn(void* arg); static void* pfn(void* arg);

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5 #define VERSION_MAJOR 5
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 71 #define VERSION_REVISION 72
#endif #endif

View file

@ -62,10 +62,19 @@ const SrsContextId& SrsThreadContext::get_id()
} }
const SrsContextId& SrsThreadContext::set_id(const SrsContextId& v) 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; ++_srs_pps_cids_set->sugar;
if (!srs_thread_self()) { if (!trd) {
_srs_context_default = v; _srs_context_default = v;
return v; return v;
} }
@ -78,16 +87,12 @@ const SrsContextId& SrsThreadContext::set_id(const SrsContextId& v)
srs_assert(r0 == 0); 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); srs_assert(r0 == 0);
return v; return v;
} }
void SrsThreadContext::clear_cid()
{
}
impl_SrsContextRestore::impl_SrsContextRestore(SrsContextId cid) impl_SrsContextRestore::impl_SrsContextRestore(SrsContextId cid)
{ {
cid_ = cid; cid_ = cid;

View file

@ -28,10 +28,13 @@ public:
virtual SrsContextId generate_id(); virtual SrsContextId generate_id();
virtual const SrsContextId& get_id(); virtual const SrsContextId& get_id();
virtual const SrsContextId& set_id(const SrsContextId& v); virtual const SrsContextId& set_id(const SrsContextId& v);
public: private:
virtual void clear_cid(); 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. // The context restore stores the context and restore it when done.
// Usage: // Usage:
// SrsContextRestore(_srs_context->get_id()); // SrsContextRestore(_srs_context->get_id());

View file

@ -412,6 +412,11 @@ void *srs_thread_getspecific(int key)
return st_thread_getspecific(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) int srs_netfd_fileno(srs_netfd_t stfd)
{ {
return st_netfd_fileno((st_netfd_t)stfd); return st_netfd_fileno((st_netfd_t)stfd);

View file

@ -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_key_create(int* keyp, void (*destructor)(void*));
extern int srs_thread_setspecific(int key, void* value); 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 void* srs_thread_getspecific(int key);
extern int srs_netfd_fileno(srs_netfd_t stfd); extern int srs_netfd_fileno(srs_netfd_t stfd);

View file

@ -133,7 +133,7 @@ VOID TEST(AppCoroutineTest, Dummy)
if (true) { if (true) {
SrsContextId v = dc.cid(); SrsContextId v = dc.cid();
EXPECT_FALSE(v.empty()); EXPECT_TRUE(v.empty());
srs_error_t err = dc.pull(); srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success); EXPECT_TRUE(err != srs_success);
@ -150,7 +150,7 @@ VOID TEST(AppCoroutineTest, Dummy)
dc.stop(); dc.stop();
SrsContextId v = dc.cid(); SrsContextId v = dc.cid();
EXPECT_FALSE(v.empty()); EXPECT_TRUE(v.empty());
srs_error_t err = dc.pull(); srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success); EXPECT_TRUE(err != srs_success);
@ -167,7 +167,7 @@ VOID TEST(AppCoroutineTest, Dummy)
dc.interrupt(); dc.interrupt();
SrsContextId v = dc.cid(); SrsContextId v = dc.cid();
EXPECT_FALSE(v.empty()); EXPECT_TRUE(v.empty());
srs_error_t err = dc.pull(); srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success); EXPECT_TRUE(err != srs_success);
@ -205,6 +205,8 @@ public:
srs_error_t r0 = srs_success; srs_error_t r0 = srs_success;
srs_cond_signal(running); srs_cond_signal(running);
// The cid should be generated if empty.
cid = _srs_context->get_id(); cid = _srs_context->get_id();
while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) { while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) {
@ -213,6 +215,9 @@ public:
srs_cond_signal(exited); srs_cond_signal(exited);
// The cid might be updated.
cid = _srs_context->get_id();
if (err != srs_success) { if (err != srs_success) {
srs_freep(r0); srs_freep(r0);
return err; 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 = &sc;
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) VOID TEST(AppCoroutineTest, StartStop)
{ {
if (true) { if (true) {