package client import ( "sync" "sync/atomic" "time" ) var callStatePool sync.Pool var zeroTime time.Time type CallState struct { ID uint64 Method string Args interface{} Result interface{} Error error DoneChan chan *CallState canceled uint32 } func (cs *CallState) done() { select { case cs.DoneChan <- cs: // ok default: // We don't want to block here. It is the caller's responsibility to make // sure the channel has enough buffer space. See comment in Go(). // if debugLog { // log.Println("rpc: discarding Call reply due to insufficient Done chan capacity") // } } } // Cancel cancels async call. // // Canceled call isn't sent to the server unless it is already sent there. // Canceled call may successfully complete if it has been already sent // to the server before Cancel call. // // It is safe calling this function multiple times from concurrently // running goroutines. func (cs *CallState) Cancel() { atomic.StoreUint32(&cs.canceled, 1) } func (cs *CallState) IsCanceled() bool { return atomic.LoadUint32(&cs.canceled) != 0 } func retainCallState() *CallState { v := callStatePool.Get() if v == nil { return &CallState{} } return v.(*CallState) } func releaseCallState(cs *CallState) { cs.Method = "" cs.Args = nil cs.Result = nil cs.Error = nil cs.DoneChan = nil callStatePool.Put(cs) }