[osal]: Use multiple status in MppThread

One thread May have multiple lock/wait/signal source:

Input  : signal source from input.
Output : signal source from output.
Control: signal source from async control operation.

Then the main working loop may stop on these lock/wait/signal points.

Change-Id: Ia6270b865cfb7087567fc21f07feb9248b929d7a
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2018-05-21 15:09:00 +08:00
parent 3ed61e06e1
commit bed754e33f
2 changed files with 35 additions and 15 deletions

View File

@@ -223,8 +223,9 @@ public:
MppThread(MppThreadFunc func, void *ctx, const char *name = NULL);
~MppThread() {};
MppThreadStatus get_status();
void set_status(MppThreadStatus status);
MppThreadStatus get_status(MppThreadSignal id = THREAD_WORK);
void set_status(MppThreadStatus status, MppThreadSignal id = THREAD_WORK);
void dump_status();
void start();
void stop();
@@ -241,7 +242,14 @@ public:
void wait(MppThreadSignal id = THREAD_WORK) {
mpp_assert(id < THREAD_SIGNAL_BUTT);
MppThreadStatus status = mStatus[id];
mStatus[id] = MPP_THREAD_WAITING;
mMutexCond[id].wait();
// check the status is not changed then restore status
if (mStatus[id] == MPP_THREAD_WAITING)
mStatus[id] = status;
}
void signal(MppThreadSignal id = THREAD_WORK) {
@@ -257,8 +265,8 @@ public:
private:
pthread_t mThread;
MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT];
MppThreadStatus mStatus[THREAD_SIGNAL_BUTT];
MppThreadStatus mStatus;
MppThreadFunc mFunction;
char mName[THREAD_NAME_LEN];
void *mContext;

View File

@@ -29,23 +29,35 @@ static RK_U32 thread_debug = 0;
#define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__)
MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name)
: mStatus(MPP_THREAD_UNINITED),
mFunction(func),
: mFunction(func),
mContext(ctx)
{
mStatus[THREAD_WORK] = MPP_THREAD_UNINITED;
mStatus[THREAD_INPUT] = MPP_THREAD_RUNNING;
mStatus[THREAD_OUTPUT] = MPP_THREAD_RUNNING;
mStatus[THREAD_CONTROL] = MPP_THREAD_RUNNING;
if (name)
strncpy(mName, name, sizeof(mName));
else
snprintf(mName, sizeof(mName), "mpp_thread");
}
MppThreadStatus MppThread::get_status()
MppThreadStatus MppThread::get_status(MppThreadSignal id)
{
return mStatus;
return mStatus[id];
}
void MppThread::set_status(MppThreadStatus status)
void MppThread::set_status(MppThreadStatus status, MppThreadSignal id)
{
mStatus = status;
mStatus[id] = status;
}
void MppThread::dump_status()
{
mpp_log("thread %s status: %d %d %d %d\n", mName,
mStatus[THREAD_WORK], mStatus[THREAD_INPUT], mStatus[THREAD_OUTPUT],
mStatus[THREAD_CONTROL]);
}
void MppThread::start()
@@ -54,9 +66,9 @@ void MppThread::start()
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
if (MPP_THREAD_UNINITED == mStatus) {
if (MPP_THREAD_UNINITED == get_status()) {
// NOTE: set status here first to avoid unexpected loop quit racing condition
mStatus = MPP_THREAD_RUNNING;
set_status(MPP_THREAD_RUNNING);
if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) {
#ifndef ARMLINUX
RK_S32 ret = pthread_setname_np(mThread, mName);
@@ -67,16 +79,16 @@ void MppThread::start()
thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n",
mName, mFunction, mContext);
} else
mStatus = MPP_THREAD_UNINITED;
set_status(MPP_THREAD_UNINITED);
}
pthread_attr_destroy(&attr);
}
void MppThread::stop()
{
if (MPP_THREAD_UNINITED != mStatus) {
if (MPP_THREAD_UNINITED != get_status()) {
lock();
mStatus = MPP_THREAD_STOPPING;
set_status(MPP_THREAD_STOPPING);
thread_dbg(MPP_THREAD_DBG_FUNCTION,
"MPP_THREAD_STOPPING status set mThread %p", this);
signal();
@@ -87,7 +99,7 @@ void MppThread::stop()
"thread %s %p context %p destroy success\n",
mName, mFunction, mContext);
mStatus = MPP_THREAD_UNINITED;
set_status(MPP_THREAD_UNINITED);
}
}