...
Run Format

Source file src/sync/cond.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package sync
     6	
     7	import (
     8		"sync/atomic"
     9		"unsafe"
    10	)
    11	
    12	// Cond implements a condition variable, a rendezvous point
    13	// for goroutines waiting for or announcing the occurrence
    14	// of an event.
    15	//
    16	// Each Cond has an associated Locker L (often a *Mutex or *RWMutex),
    17	// which must be held when changing the condition and
    18	// when calling the Wait method.
    19	//
    20	// A Cond can be created as part of other structures.
    21	// A Cond must not be copied after first use.
    22	type Cond struct {
    23		noCopy noCopy
    24	
    25		// L is held while observing or changing the condition
    26		L Locker
    27	
    28		notify  notifyList
    29		checker copyChecker
    30	}
    31	
    32	// NewCond returns a new Cond with Locker l.
    33	func NewCond(l Locker) *Cond {
    34		return &Cond{L: l}
    35	}
    36	
    37	// Wait atomically unlocks c.L and suspends execution
    38	// of the calling goroutine. After later resuming execution,
    39	// Wait locks c.L before returning. Unlike in other systems,
    40	// Wait cannot return unless awoken by Broadcast or Signal.
    41	//
    42	// Because c.L is not locked when Wait first resumes, the caller
    43	// typically cannot assume that the condition is true when
    44	// Wait returns. Instead, the caller should Wait in a loop:
    45	//
    46	//    c.L.Lock()
    47	//    for !condition() {
    48	//        c.Wait()
    49	//    }
    50	//    ... make use of condition ...
    51	//    c.L.Unlock()
    52	//
    53	func (c *Cond) Wait() {
    54		c.checker.check()
    55		t := runtime_notifyListAdd(&c.notify)
    56		c.L.Unlock()
    57		runtime_notifyListWait(&c.notify, t)
    58		c.L.Lock()
    59	}
    60	
    61	// Signal wakes one goroutine waiting on c, if there is any.
    62	//
    63	// It is allowed but not required for the caller to hold c.L
    64	// during the call.
    65	func (c *Cond) Signal() {
    66		c.checker.check()
    67		runtime_notifyListNotifyOne(&c.notify)
    68	}
    69	
    70	// Broadcast wakes all goroutines waiting on c.
    71	//
    72	// It is allowed but not required for the caller to hold c.L
    73	// during the call.
    74	func (c *Cond) Broadcast() {
    75		c.checker.check()
    76		runtime_notifyListNotifyAll(&c.notify)
    77	}
    78	
    79	// copyChecker holds back pointer to itself to detect object copying.
    80	type copyChecker uintptr
    81	
    82	func (c *copyChecker) check() {
    83		if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
    84			!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
    85			uintptr(*c) != uintptr(unsafe.Pointer(c)) {
    86			panic("sync.Cond is copied")
    87		}
    88	}
    89	
    90	// noCopy may be embedded into structs which must not be copied
    91	// after the first use.
    92	//
    93	// See https://github.com/golang/go/issues/8005#issuecomment-190753527
    94	// for details.
    95	type noCopy struct{}
    96	
    97	// Lock is a no-op used by -copylocks checker from `go vet`.
    98	func (*noCopy) Lock() {}
    99	

View as plain text