mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-02 20:08:21 +08:00
thread_cond::wait add locked parameter for one locking condition
This commit is contained in:
parent
d0d856c33f
commit
6caa04227d
@ -1,5 +1,9 @@
|
||||
修改历史列表:
|
||||
|
||||
525) 2018.6.15
|
||||
525.1) feature: thread_cond 类中的 wait 方法参加参数 locked,内部会先判断该
|
||||
参数决定是否需要加锁
|
||||
|
||||
524) 2018.6.4
|
||||
524.1) feature: connect_monitor 类增加三个虚方法:on_connected, on_refused,
|
||||
on_timeout
|
||||
|
@ -45,9 +45,14 @@ public:
|
||||
* > 0 时表示等待超时的时间
|
||||
* == 0,不等待
|
||||
* < 0 则一直等待直到条件变量就绪
|
||||
* @param locked {bool} 当构造参数传入的线程锁非空时,该参数表示外部
|
||||
* 传入的线程锁是否已经被外部调用者锁住,如果已经被锁住,则内部将不
|
||||
* 再对构造中传入的外部锁加锁,否则,内部将会加锁外部锁,函数返回前
|
||||
* 再解外部锁;此外,如果构造参数传入线程锁为空时,内部会自动先加内
|
||||
* 部锁,函数返回前再解内部锁
|
||||
* @return {bool} 返回 true 表示条件变量就绪,否则表示超时或没被通知
|
||||
*/
|
||||
bool wait(long long microseconds = -1);
|
||||
bool wait(long long microseconds = -1, bool locked = false);
|
||||
|
||||
/**
|
||||
* 通知一个或几个等待在线程条件变量上的线程,表示条件变量就结
|
||||
@ -76,7 +81,10 @@ public:
|
||||
private:
|
||||
thread_mutex* mutex_;
|
||||
thread_mutex* mutex_internal_;
|
||||
acl_pthread_cond_t* cond_;
|
||||
acl_pthread_cond_t* cond_;
|
||||
|
||||
bool wait(bool locked);
|
||||
bool timed_wait(long long microseconds, bool locked);
|
||||
};
|
||||
|
||||
} // namespace acl
|
||||
|
@ -55,61 +55,97 @@ bool thread_cond::notify_all(void)
|
||||
return acl_pthread_cond_broadcast(cond_) == 0;
|
||||
}
|
||||
|
||||
bool thread_cond::wait(long long microseconds /* = -1 */)
|
||||
{
|
||||
#define SEC_TO_NS 1000000000 // nanoseconds per second
|
||||
#define SEC_TO_MIS 1000000 // microseconds per second
|
||||
#define MIS_TO_NS 1000 // nanoseconds per microseconds
|
||||
|
||||
acl_pthread_mutex_t* mutex = mutex_->get_mutex();
|
||||
if (mutex_->lock() == false)
|
||||
bool thread_cond::wait(long long microseconds /* = -1 */,
|
||||
bool locked /* = false */)
|
||||
{
|
||||
if (microseconds >= 0)
|
||||
return timed_wait(microseconds, locked);
|
||||
else
|
||||
return wait(locked);
|
||||
}
|
||||
|
||||
bool thread_cond::wait(bool locked)
|
||||
{
|
||||
bool locked_internal;
|
||||
|
||||
// 如果使用了内部锁,则需要加锁,否则再判断所用的外部锁是否已经加锁,
|
||||
// 如果使用了外部锁且外部未加锁,则也需要加锁。
|
||||
if (mutex_internal_ || !locked)
|
||||
{
|
||||
logger_error("lock error!");
|
||||
if (!mutex_->lock())
|
||||
{
|
||||
logger_error("lock error=%s", last_serror());
|
||||
return false;
|
||||
}
|
||||
locked_internal = true;
|
||||
}
|
||||
else
|
||||
locked_internal = false;
|
||||
|
||||
int ret = acl_pthread_cond_wait(cond_, mutex_->get_mutex());
|
||||
if (ret)
|
||||
{
|
||||
#ifdef ACL_UNIX
|
||||
acl_set_error(ret);
|
||||
#endif
|
||||
logger_error("pthread_cond_wait error %s", last_serror());
|
||||
}
|
||||
|
||||
// 如果本方法内部前面加了锁,则此处需要解锁
|
||||
if (locked_internal && !mutex_->unlock())
|
||||
{
|
||||
logger_error("mutex unlock error=%s", last_serror());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (microseconds < 0)
|
||||
{
|
||||
int ret1 = acl_pthread_cond_wait(cond_, mutex) ;
|
||||
if (ret1)
|
||||
{
|
||||
#ifdef ACL_UNIX
|
||||
acl_set_error(ret1);
|
||||
#endif
|
||||
logger_error("pthread_cond_wait error %s",
|
||||
last_serror());
|
||||
}
|
||||
|
||||
bool ret2 = mutex_->unlock();
|
||||
if (!ret2)
|
||||
logger_error("mutex unlock error");
|
||||
return ret1 == 0 && ret2;
|
||||
}
|
||||
return ret == 0 ? true : false;
|
||||
}
|
||||
|
||||
bool thread_cond::timed_wait(long long microseconds, bool locked)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
struct timespec ts;
|
||||
ts.tv_sec = (time_t) (tv.tv_sec + microseconds / SEC_TO_MIS);
|
||||
long long n = (tv.tv_usec + microseconds % SEC_TO_MIS) * MIS_TO_NS;
|
||||
ts.tv_nsec = (long) n % SEC_TO_NS;
|
||||
ts.tv_sec += (long) n / SEC_TO_NS;
|
||||
|
||||
int ret1 = acl_pthread_cond_timedwait(cond_, mutex, &ts);
|
||||
if (ret1)
|
||||
bool locked_internal;
|
||||
if (mutex_internal_ || !locked)
|
||||
{
|
||||
if (!mutex_->lock())
|
||||
{
|
||||
logger_error("lock error=%s", last_serror());
|
||||
return false;
|
||||
}
|
||||
locked_internal = true;
|
||||
}
|
||||
else
|
||||
locked_internal = false;
|
||||
|
||||
int ret = acl_pthread_cond_timedwait(cond_, mutex_->get_mutex(), &ts);
|
||||
if (ret)
|
||||
{
|
||||
#ifdef ACL_UNIX
|
||||
acl_set_error(ret1);
|
||||
acl_set_error(ret);
|
||||
#endif
|
||||
if (ret1 != ACL_ETIMEDOUT)
|
||||
logger_error("pthread_cond_timedwait error %s",
|
||||
if (ret != ACL_ETIMEDOUT)
|
||||
logger_error("pthread_cond_timedwait error=%s",
|
||||
last_serror());
|
||||
}
|
||||
|
||||
bool ret2 = mutex_->unlock();
|
||||
if (!ret2)
|
||||
logger_error("mutex unlock error");
|
||||
return ret1 == 0 && ret2;
|
||||
if (locked_internal && !mutex_->unlock())
|
||||
{
|
||||
logger_error("mutex unlock error=%s", last_serror());
|
||||
return false;
|
||||
}
|
||||
|
||||
return ret == 0 ? true : false;
|
||||
}
|
||||
|
||||
thread_mutex& thread_cond::get_mutex(void) const
|
||||
|
Loading…
Reference in New Issue
Block a user