func (e *CElement) SetNext(newNext *CElement) {
	e.mtx.Lock()
	defer e.mtx.Unlock()
	oldNext := e.next
	e.next = newNext
	if oldNext != nil && newNext == nil {
		e.nextWg = waitGroup1()  
		e.nextWaitCh = make(chan struct{})
	}
	if oldNext == nil && newNext != nil {
		e.nextWg.Done()
		close(e.nextWaitCh)
	}
}
NOTE: This function needs to be safe for
concurrent goroutines waiting on nextWg.
package clist
import (
	"sync"
)
type CElement struct {
	mtx        sync.RWMutex
	prev       *CElement
	prevWg     *sync.WaitGroup
	prevWaitCh chan struct{}
	next       *CElement
	nextWg     *sync.WaitGroup
	nextWaitCh chan struct{}
	removed    bool
	Value interface{}  
}
func (e *CElement) NextWait() *CElement {
	for {
		e.mtx.RLock()
		next := e.next
		nextWg := e.nextWg
		removed := e.removed
		e.mtx.RUnlock()
		if next != nil || removed {
			return next
		}
		nextWg.Wait()
	}
}
func (e *CElement) PrevWait() *CElement {
	for {
		e.mtx.RLock()
		prev := e.prev
		prevWg := e.prevWg
		removed := e.removed
		e.mtx.RUnlock()
		if prev != nil || removed {
			return prev
		}
		prevWg.Wait()
	}
}
func (e *CElement) PrevWaitChan() <-chan struct{} {
	e.mtx.RLock()
	defer e.mtx.RUnlock()
	return e.prevWaitCh
}
func (e *CElement) NextWaitChan() <-chan struct{} {
	e.mtx.RLock()
	defer e.mtx.RUnlock()
	return e.nextWaitCh
}
func (e *CElement) Next() *CElement {
	e.mtx.RLock()
	defer e.mtx.RUnlock()
	return e.next
}
func (e *CElement) Prev() *CElement {
	e.mtx.RLock()
	defer e.mtx.RUnlock()
	return e.prev
}
func (e *CElement) Removed() bool {
	e.mtx.RLock()
	defer e.mtx.RUnlock()
	return e.removed
}
func (e *CElement) DetachNext() {
	if !e.Removed() {
		panic("DetachNext() must be called after Remove(e)")
	}
	e.mtx.Lock()
	defer e.mtx.Unlock()
	e.next = nil
}
func (e *CElement) DetachPrev() {
	if !e.Removed() {
		panic("DetachPrev() must be called after Remove(e)")
	}
	e.mtx.Lock()
	defer e.mtx.Unlock()
	e.prev = nil
}