BIND 10 #2332: define and implement wrapper interface for conditional variables
BIND 10 Development
do-not-reply at isc.org
Wed Oct 10 08:27:31 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:6 jinmei]:
> {{{#!cpp
> // This class object internally holds pthread_cond_t and pthread_mutex_t
> class CondVar : boost::noncopyable {
> public:
> typedef boost::shared_ptr<Mutex::Locker> LockerPtr;
>
> CondVar(); // do pthread_cond_init() and pthread_mutex_init()
> ~CondVar(); // do pthread_cond_destroy() and pthread_mutex_destroy()
>
> // acquire internal mutex, reset (i.e. release) locker, then call
> // pthread_cond_wait with the internal cond and mutex. on wake up,
> // release the internal mutex, create a new locker pointer for the
> // passed mutex (acquiring the lock) and return it.
> LockerPtr wait(LockerPtr locker, Mutex& mutex);
>
> // acquire internal mutex, call pthread_cond_signal(), then release
the
> // internal lock.
> void signal();
> };
> }}}
>
> The main point is to give the user of the `CondVar` class full
> ownership of the locker. We wouldn't like to allow the configurator
> thread to hold the lock too long, e.g, while it works on loading a big
> zone. But we'd also not like to allow arbitrary user classes to call
> `Mutex::lock()` or `Mutex::unlock()`. Hence the use of (shared)
> pointer to `Mutex::Locker`. With this approach, the `CondVar` class
> itself doesn't have to know other details of `Mutex` internal, so it
> doesn't have to be a friend.
I'm not sure I understand the interface. But there are some things that
scare me.
Are there two mutexes in the game (internal and the passed to wait) or
just
one? If just one, how does the caller lock? If two, how do they interact?
And
if they interact, is it guaranteed to be race-condition-free and deadlock-
free?
Don't forget, the mutex is not for the protection of the condition
variable, it
is for the shared state around it. The whole trick with condvars is that
the
wait unlocks the mutex protecting the data atomically. Also, can multiple
threads wait on the same condition variable? I'm not saying your approach
is
necessarily wrong, but it's not obvious it works and would need some kind
of
proof.
Also, you don't need to lock for signal, it's save in either state of the
mutex
(in my understanding, there's only difference in performance and it is
case by
case dependant on which mode of operation is faster).
But what scares me is the shared pointer with the locker. The locker is
meant
to be generally allocated on stack, for obvious reasons. The approach with
dynamic allocation has disadvantages in both less convenient operation and
being more error-prone. I think you're trading this in favor of not having
a
friend declaration. I'd rather have the complexity hidden inside than
passing
it onto the caller.
--
Ticket URL: <http://bind10.isc.org/ticket/2332#comment:7>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development
More information about the bind10-tickets
mailing list