thread_cond::wait add locked parameter for one locking condition

This commit is contained in:
zsx 2018-06-15 15:25:09 +08:00
parent d0d856c33f
commit 72f3d59b79
4 changed files with 86 additions and 35 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
%define release_id 5
%define release_id 6
Summary: The powerful c/c++ library and server framework
Name: acl-libs
@ -133,6 +133,9 @@ fi
%changelog
* Fri Jun 15 2018 zhengshuxin@qiyi.com 3.4.1-5-20180615.15
- thread_cond::wait add locked parameter for one locking condition
* Tue Jun 04 2018 zhengshuxin@qiyi.com 3.4.1-5-20180605.14
- check_client: just choose one from on_refused and on_timeout to report connection status