C++ pthread封装

#ifndef __HI_MW_THREAD_H__
#define __HI_MW_THREAD_H__

#include <pthread.h>
#include <unistd.h>
#include "hi_type.h"

/*
 * HiMWThread Event callback. Used for listen running state.
 */
class HiMWThread;
class IHiMWThreadEvt
{
public:
    virtual void onHiMWThreadExit(HiMWThread* pHiMWThread) = 0;
    virtual ~IHiMWThreadEvt(){}
};

/*
 * Base HiMWThread class.  The implementation is system-dependent.
 */
class HiMWThread
{
public:
    typedef void (*HiMWThreadFunc)(const void* arg);

    typedef struct {
        volatile bool wait;   /* enable or disable HiMWThread */
        volatile bool once;   /* select loop once or always */
        volatile bool exit;   /* exit and recovery resource */
    } HiMWThreadStat;

    typedef enum {
        ONCE   = 0x1 << 0,  /* just loop once */
        REPEAT = 0x1 << 1,  /* repeat loop  */
        WAIT   = 0x1 << 2,  /* wait for resume,only valid at first running */
    } HiMWThreadFlag;
public:
    HiMWThread(HiMWThreadFunc func = NULL, const void* arg = NULL, IHiMWThreadEvt* pEvt = NULL);
    virtual ~HiMWThread();

    void run(unsigned int flag = ONCE);
    void suspend();
    void resume();
    void exit();/* quit immediately */
    void exitAndJoin();

protected:
    virtual void run(const void* arg){HI_UNUSED(arg);};
private:
    static void* loop(void* arg);
    void task();
private:
    HiMWThreadFunc  mThreadFunc;
    const void*     mArg;
    IHiMWThreadEvt* mEvt;
    pthread_t       mId;
    HiMWThreadStat  mStat;
    pthread_mutex_t mLock;
    pthread_cond_t  mCond;
};
#endif /*__HI_MW_THREAD_H__*/


#define LOG_NDEBUG 0
#define LOG_TAG "HiMW@Hi_mw_thread.cpp"

#include "hi_mw_thread.h"
#include "hi_mw_log.h"
#include "hi_mw_common.h"

HiMWThread::HiMWThread(HiMWThreadFunc func, const void* arg, IHiMWThreadEvt* pEvt)
    : mThreadFunc(func), mArg(arg), mEvt(pEvt), mId(0)
{
    mStat.wait = false;
    mStat.once = false;
    mStat.exit = true;
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_init(&mLock, NULL);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);

    s32Ret = pthread_cond_init(&mCond, NULL);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);
}

HiMWThread::~HiMWThread()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
        s32Ret = pthread_mutex_unlock(&mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);
  
        s32Ret = pthread_join(mId, NULL);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);
    }
    else
    {
        s32Ret = pthread_mutex_unlock(&mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);
    }

    s32Ret = pthread_mutex_destroy(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);

    s32Ret = pthread_cond_destroy(&mCond);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_init fail, ret:0x%x", s32Ret);
}

void HiMWThread::exit()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
        mStat.exit = true;
        mStat.wait = false;
        s32Ret = pthread_cond_signal(&mCond);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_signal fail, ret:0x%x", s32Ret);
    }
    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
    //if (mEvt) mEvt->onHiMWThreadExit(this);
}

void HiMWThread::exitAndJoin()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
       mStat.exit = true;
       mStat.wait = false;

       s32Ret = pthread_cond_signal(&mCond);
       RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_signal fail, ret:0x%x", s32Ret);

       s32Ret = pthread_mutex_unlock(&mLock);
       RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);

       s32Ret = pthread_join(mId, NULL);
       RET_CHECK_ERR_LOG(s32Ret, "pthread_join fail, ret:0x%x", s32Ret);
       return;
    }

    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);

    LOGW("Thread not run");
}

void HiMWThread::run(unsigned int flag)
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
        mStat.exit = true;
        mStat.wait = false;

        s32Ret = pthread_cond_signal(&mCond);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_signal fail, ret:0x%x", s32Ret);

        s32Ret = pthread_mutex_unlock(&mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);

        s32Ret = pthread_join(mId, NULL);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_join fail, ret:0x%x", s32Ret);

        s32Ret = pthread_mutex_lock(&mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);
    }

    mStat.exit = false;
    mStat.wait = true;
    mStat.once = flag & ONCE;

    if (~flag & WAIT)
    {
        mStat.wait = false;
    }
    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);

    s32Ret = pthread_create(&mId, NULL, loop, this);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_create fail, ret:0x%x", s32Ret);
}

void HiMWThread::suspend()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
        if (mStat.wait)
        {
            s32Ret = pthread_mutex_unlock(&mLock);
            RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
            return;
        }

        mStat.wait = true;
    }
    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
}

void HiMWThread::resume()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    if (!mStat.exit)
    {
        if (!mStat.wait)
        {
            s32Ret = pthread_mutex_unlock(&mLock);
            RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
            return;
        }

        mStat.wait = false;
        s32Ret = pthread_cond_signal(&mCond);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_signal fail, ret:0x%x", s32Ret);
    }
    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
}

void* HiMWThread::loop(void* arg)
{
    HiMWThread* ptr = reinterpret_cast<HiMWThread*>(arg);

    while (!ptr->mStat.exit)
    {
        ptr->task();
    }

    if (ptr->mEvt)
    {
        ptr->mEvt->onHiMWThreadExit(ptr);
    }

    return NULL;
}

void HiMWThread::task()
{
    HI_S32 s32Ret = HI_SUCCESS;
    s32Ret = pthread_mutex_lock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_lock fail, ret:0x%x", s32Ret);

    while (mStat.wait)
    {
        s32Ret = pthread_cond_wait(&mCond, &mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_cond_wait fail, ret:0x%x", s32Ret);
    }

    if (mStat.exit)
    {
        s32Ret = pthread_mutex_unlock(&mLock);
        RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);
        return;
    }

    mStat.wait = mStat.once;
    s32Ret = pthread_mutex_unlock(&mLock);
    RET_CHECK_ERR_LOG(s32Ret, "pthread_mutex_unlock fail, ret:0x%x", s32Ret);

    if (!mThreadFunc)
    {
        return run(mArg);
    }

    return mThreadFunc(mArg);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坂田民工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值