fn recv<'a>(
        &'a self,
        mut data: MutexGuard<'a, Data<T>>,
        try: bool,
    ) -> RecvOp<'a, T> {
        while data.user.len() == 0 {
            if data.closed {
                return RecvOp::closed(data);
            }
            if try {
                return RecvOp::blocked(data);
            }
            if self.ty == ChannelType::Rendezvous {
                self.notify();
            }
            data.waiting_recv += 1;
            data = self.cond.wait(data).unwrap();
            data.waiting_recv -= 1;
        }
        let val = data.user.pop();
        self.notify();
        RecvOp::ok(data, val)
    }
// The following are all of the core channel operations wrapped up in a
// pretty bow. They all follow a reasonably similar pattern (with the
// rendezvous `send` diverging the most) which is roughly:
//
// 1. Accept locked access to the channel's data.
// 2. Check if the operation can continue. (For sends, we block if the
//    buffer is full. For receives, we block if the buffer is empty.)
// 2a. If we need to block, then we release the mutex given to us and
//     block on a condition variable.
// 2b. When awoken, go to (2).
// 3. If we don't need to block, then we are guaranteed to synchronize*
//    either by adding a value to the buffer or removing a value.
// 4. Wake all other senders and receivers that are blocked on the
//    same condition variable mentioned in (2a).
//
// * Not true for sending on rendezvous channels, since we need to make
// sure that a recv consumes the value.
//
// Interestingly, the recv operation for all three types of channels
// is exactly the same (modulo the underlying data structure).
The following are all of the core channel operations wrapped up in a
pretty bow. They all follow a reasonably similar pattern (with the
rendezvous `send` diverging the most) which is roughly.

1. Accept locked access to the channel's data.
2. Check if the operation can continue. (For sends, we block if the
buffer is full. For receives, we block if the buffer is empty.)
2a. If we need to block, then we release the mutex given to us and
block on a condition variable.
2b. When awoken, go to (2).
3. If we don't need to block, then we are guaranteed to synchronize
either by adding a value to the buffer or removing a value.
4. Wake all other senders and receivers that are blocked on the
same condition variable mentioned in (2a).

Not true for sending on rendezvous channels, since we need to make
sure that a recv consumes the value.

Interestingly, the recv operation for all three types of channels
is exactly the same (modulo the underlying data structure).
The following are all of the core channel operations wrapped up in a pretty bow . They all follow a reasonably similar pattern ( with the rendezvous ` send ` diverging the most ) which is roughly . 1 . Accept locked access to the channel ' s data . 2 . Check if the operation can continue . ( For sends we block if the buffer is full . For receives we block if the buffer is empty . ) 2a . If we need to block then we release the mutex given to us and block on a condition variable . 2b . When awoken go to ( 2 ) . 3 . If we don ' t need to block then we are guaranteed to synchronize either by adding a value to the buffer or removing a value . 4 . Wake all other senders and receivers that are blocked on the same condition variable mentioned in ( 2a ) . Not true for sending on rendezvous channels since we need to make sure that a recv consumes the value . Interestingly the recv operation for all three types of channels is exactly the same ( modulo the underlying data structure ) .
fn recv<'a>(
        &'a self,
        mut data: MutexGuard<'a, Data<T>>,
        try: bool,
    ) -> RecvOp<'a, T> {
        while data.user.len() == 0 {
            if data.closed {
                return RecvOp::closed(data);
            }
            if try {
                return RecvOp::blocked(data);
            }
            if self.ty == ChannelType::Rendezvous {
                self.notify();
            }
            data.waiting_recv += 1;
            data = self.cond.wait(data).unwrap();
            data.waiting_recv -= 1;
        }
        let val = data.user.pop();
        self.notify();
        RecvOp::ok(data, val)
    }
fn recv < ' a > ( & ' a self , mut data : MutexGuard < ' a , Data < T > > , try : bool , ) -> RecvOp < ' a , T > { while data . user . len ( ) == 0 { if data . closed { return RecvOp :: closed ( data ) ; } if try { return RecvOp :: blocked ( data ) ; } if self . ty == ChannelType :: Rendezvous { self . notify ( ) ; } data . waiting_recv += 1 ; data = self . cond . wait ( data ) . unwrap ( ) ; data . waiting_recv -= 1 ; } let val = data . user . pop ( ) ; self . notify ( ) ; RecvOp :: ok ( data , val ) }
The following are all of the core channel operations wrapped up in a
pretty bow.
The following are all of the core channel operations wrapped up in a pretty bow .
&'a self
data
MutexGuard<'a, Data<T>>
try
bool
&'a self
data
MutexGuard<'a, Data<T>>
try
bool