|
发表于 2009-4-23 13:58:02
|
显示全部楼层
下面是set的源代码,从源代码分析,你的结果是正确的,我之前的认识是有偏差的。
只有在第一次set的时候,才会广播所有的观察者。
需要注意的是代码的注释说,广播之后会删除所有观察者,但是我从代码里并没有看到这一点。
我做了测试验证了确实观察者并没有从队列中被移除,
因此只要你在取出值之后,将value_ 置为0,下次观察者即可以被调用到。
不过很可惜,尽管ACE_Future提供了get_rep函数,可以获得内部ACE_Future_Rep<T>的指针,
不过这样使用的隐患太大,而且并没提供类似功能的函数,
所以要实现这个功能可能得自己动手改一下源代码了。
template <class T> int
ACE_Future_Rep<T>::set (const T &r,
ACE_Future<T> &caller)
{
// If the value is already produced, ignore it...
if (this->value_ == 0)
{
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
ace_mon,
this->value_ready_mutex_,
-1));
// Otherwise, create a new result value. Note the use of the
// Double-checked locking pattern to avoid multiple allocations.
if (this->value_ == 0) // Still no value, so proceed
{
ACE_NEW_RETURN (this->value_,
T (r),
-1);
// Remove and notify all subscribed observers.
typename OBSERVER_COLLECTION::iterator iterator =
this->observer_collection_.begin ();
typename OBSERVER_COLLECTION::iterator end =
this->observer_collection_.end ();
while (iterator != end)
{
OBSERVER *observer = *iterator++;
observer->update (caller);
}
// Signal all the waiting threads.
return this->value_ready_.broadcast ();
}
// Destructor releases the lock.
}
return 0;
} |
|