BIND 10 #2332: define and implement wrapper interface for conditional variables
BIND 10 Development
do-not-reply at isc.org
Wed Oct 10 19:08:11 UTC 2012
#2332: define and implement wrapper interface for conditional variables
-------------------------------------+-------------------------------------
Reporter: | Owner:
jinmei | Status: new
Type: task | Milestone:
Priority: | Sprint-20121023
medium | Resolution:
Component: | Sensitive: 0
b10-auth | Sub-Project: DNS
Keywords: | Estimated Difficulty: 5
Defect Severity: N/A | Total Hours: 0
Feature Depending on Ticket: |
background zone loading |
Add Hours to Ticket: 0 |
Internal?: 0 |
-------------------------------------+-------------------------------------
Comment (by vorner):
Hello
Replying to [comment:8 jinmei]:
> I didn't think it possible to resolve this situation through making
> `CondVar` a friend of `Mutex`, hence the introduction of pointer to
> `Locker`. With that introduction `CondVar` simply didn't have to be a
> friend of `Mutex`, and that's why I didn't make it so.
>
> I see the concerns you had in this proposal, and I don't think this
> one is the best one in terms of complexity and understandability. If
> there's a design to make it possible in a safe and more
> understandable, I'm happy to use it. Do you have a concrete proposal?
Well, for one, I always used the condvars with single mutex only, not two.
And
I think it is easier to grasp. I don't know why boost used two, but I
don't see
a reason for us. I guess they didn't document a reason for doing so in
their
case and consider boost many things, but simple is really not one of them.
And if we made CondVar friend of Mutex and put CondVar into the same C++
file
(so it would know the Impl of Mutex), we could write directly something
like
this:
{{{#!c++
void
CondVar::wait(Mutex& mutex) {
assert(mutex.locked());
pthread_cond_wait(impl_->condvar, mutex.impl_->mutex);
}
}}}
It does indeed make CondVar and Mutex very close friends, but they are
indeed
quite related. But then we can rewrite your example as:
{{{#!c++
void
run() {
// some kind of mutex to protect the command queue, shared with the
main
// thread.
Mutex mutex;
CondVar condvar; // shared with the main thread
while (true) {
Command command;
{
Mutex::Locker locker(mutex);
while (queue.empty()) {
condvar.wait(mutex); // Here we pass locked mutex. As
pthread condvar wants.
}
// at this point mutex is locked and queue is not empty
command = queue.pop();
} // release the mutex as the following would be time consuming
// do something based on command: reload a zone, reconfigure
entire
// data source clients, or shutdown the thread, etc.
}
}
}}}
> And, one more thing: I also tend to agree that using `Locker` through
> a pointer could be considered a kind of abuse, but if so, I think the
> documentation should state that more clearly. It currently reads:
>
> {{{#!cpp
> /// If you create the locker on the stack or using some other
"garbage
> /// collecting" mechanism (auto_ptr, for example), it ensures
exception
> /// safety with regards to the mutex - it'll get released on the
exit
> /// of function no matter by what means.
> }}}
>
> This looks like it's actually expected to be used through auto_ptr,
> even though it's not explicitly encouraged. If such usage is rather
> discouraged IMO we should say something like "even if something like
> this is possible, it's generally discouraged".
Well, auto_ptr still seems better than shared_ptr, because you have just
one
instance. When you do a release on shared_ptr, you never know if someone
else
is still holding it or not. Anyway, I'm not against discouraging it more.
I'm
OK with discussing using it when the situation requires, but I'd hate to
_require_ it through one of our interfaces.
--
Ticket URL: <http://bind10.isc.org/ticket/2332#comment:9>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list