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