func chanOfRecv() { // MakeChan(<-chan) is a no-op. t := reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(&a)) print(reflect.Zero(t).Interface()) // @types <-chan *int print(reflect.MakeChan(t, 0).Interface().(<-chan *int)) // @pointsto print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto }
func chanOfSend() { // MakeChan(chan<-) is a no-op. t := reflect.ChanOf(reflect.SendDir, reflect.TypeOf(&a)) print(reflect.Zero(t).Interface()) // @types <-chan *int | chan<- *int | chan *int print(reflect.MakeChan(t, 0).Interface().(chan<- *int)) // @pointsto print(reflect.MakeChan(t, 0).Interface().(chan *int)) // @pointsto <alloc in reflect.MakeChan> }
func MakeChannel(id string, fromClientStruct interface{}, toClientStruct interface {})(fromClient unknownTypeChan,toclient unknownTypeChan) { fromClient=reflect.MakeChan(fromClientStruct,1) toclient=reflect.MakeChan(toClientStruct,1) }
func NewChan(typ interface{}) (interface{}, interface{}) { rc := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(typ)), 0) wc := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(typ)), 0) go loop(rc, wc) vrc := rc.Convert(reflect.ChanOf(reflect.RecvDir, reflect.TypeOf(typ))) vwc := wc.Convert(reflect.ChanOf(reflect.SendDir, reflect.TypeOf(typ))) return vrc.Interface(), vwc.Interface() }
// executeCmd runs Store.ExecuteCmd in a goroutine. A channel with // element type equal to the reply type is created and returned // immediately. The reply is sent to the channel once the cmd has been // executed by the store. The store is looked up from the store map // if specified by header.Replica; otherwise, the command is being // executed locally, and the replica is determined via lookup of // header.Key in the ranges slice. func (db *LocalDB) executeCmd(method string, header *storage.RequestHeader, args, reply interface{}) interface{} { chanVal := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(reply)), 1) replyVal := reflect.ValueOf(reply) go func() { // If the replica isn't specified in the header, look it up. var err error var store *storage.Store // If we aren't given a Replica, then a little bending over backwards here. We need to find the Store, but all // we have is the Key. So find its Range locally, and pull out its Replica which we use to find the Store. // This lets us use the same codepath below (store.ExecuteCmd) for both locally and remotely originated // commands. if header.Replica.NodeID == 0 { if repl := db.lookupReplica(header.Key); repl != nil { header.Replica = *repl } else { err = util.Errorf("unable to lookup range replica for key %q", string(header.Key)) } } if err == nil { store, err = db.GetStore(&header.Replica) } if err != nil { reflect.Indirect(replyVal).FieldByName("Error").Set(reflect.ValueOf(err)) } else { store.ExecuteCmd(method, header, args, reply) } chanVal.Send(replyVal) }() return chanVal.Interface() }
// TakeChan is of type: func(num int, input chan T) chan T. // Accept only the given number of items from the input chan. After that number // has been received, all input messages will be ignored and the output channel // will be closed. func TakeChan(num int, input interface{}) interface{} { inputValue := reflect.ValueOf(input) if inputValue.Kind() != reflect.Chan { panic(fmt.Sprintf("DropChan called on invalid type: %s", inputValue.Type())) } output := reflect.MakeChan(inputValue.Type(), 0) var count int go func() { // only send num items for count = 0; count < num; count++ { item, ok := inputValue.Recv() if !ok { break } output.Send(item) } // sent our max, close the channel output.Close() }() return output.Interface() }
// FilterChan is of type: func(fn func(T) bool, input chan T) chan T. // Apply a filtering function to a chan, which will only pass through // items when the filter func returns true. func FilterChan(fn, input interface{}) interface{} { checkFilterFuncType(fn, input) inputValue := reflect.ValueOf(input) fnValue := reflect.ValueOf(fn) if inputValue.Kind() != reflect.Chan { panic(fmt.Sprintf("FilterChan called on invalid type: %s", inputValue.Type())) } output := reflect.MakeChan(inputValue.Type(), 0) go func() { for { item, ok := inputValue.Recv() if !ok { break } if fnValue.Call([]reflect.Value{item})[0].Bool() { output.Send(item) } } output.Close() }() return output.Interface() }
// executeCmd runs Store.ExecuteCmd in a goroutine. A channel with // element type equal to the reply type is created and returned // immediately. The reply is sent to the channel once the cmd has been // executed by the store. The store is looked up from the store map // if specified by header.Replica; otherwise, the command is being // executed locally, and the replica is determined via lookup of // header.Key in the ranges slice. func (db *LocalDB) executeCmd(method string, header *storage.RequestHeader, args, reply interface{}) interface{} { chanVal := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(reply)), 1) replyVal := reflect.ValueOf(reply) go func() { // If the replica isn't specified in the header, look it up. var err error var store *storage.Store if header.Replica.NodeID == 0 { if repl := db.lookupReplica(header.Key); repl != nil { header.Replica = *repl } else { err = util.Errorf("unable to lookup range replica for key %q", string(header.Key)) } } if err == nil { store, err = db.GetStore(&header.Replica) } if err != nil { reflect.Indirect(replyVal).FieldByName("Error").Set(reflect.ValueOf(err)) } else { store.ExecuteCmd(method, header, args, reply) } chanVal.Send(replyVal) }() return chanVal.Interface() }
func zero(head P, mid string, typ reflect.Type) (value reflect.Value, err error) { switch typ.Kind() { case reflect.Ptr: value = reflect.New(typ.Elem()) case reflect.Map: value = reflect.MakeMap(typ) case reflect.Slice: value = reflect.MakeSlice(typ, 0, 0) case reflect.Chan: value = reflect.MakeChan(typ, 1) case reflect.Func, reflect.Interface, reflect.UnsafePointer: value = reflect.Zero(typ) case reflect.Invalid: err = fmt.Errorf("unable to create '%s' at '%s'", typ, append(head, mid)) default: value = reflect.Zero(typ) } return }
// DropChan is of type: func(num int, input chan T) chan T. // Drop a given number of items from the input chan. After that number has been // dropped, the rest are passed straight through. func DropChan(num int, input interface{}) interface{} { inputValue := reflect.ValueOf(input) if inputValue.Kind() != reflect.Chan { panic(fmt.Sprintf("DropChan called on invalid type: %s", inputValue.Type())) } output := reflect.MakeChan(inputValue.Type(), 0) var count int go func() { // drop num items for count = 0; count < num; count++ { _, ok := inputValue.Recv() if !ok { // channel closed early output.Close() return } } // Return the rest for { item, ok := inputValue.Recv() if !ok { break } output.Send(item) } output.Close() }() return output.Interface() }
// TakeWhileChan is of type: func(fn func(T) bool, input chan T) chan T. // Accept items from the input chan until the given function returns false. // After that, all input messages will be ignored and the output channel will // be closed. func TakeWhileChan(fn, input interface{}) interface{} { checkTakeWhileFuncType(fn, input) inputValue := reflect.ValueOf(input) fnValue := reflect.ValueOf(fn) output := reflect.MakeChan(inputValue.Type(), 0) go func() { for { item, ok := inputValue.Recv() if !ok { break } // check if we should continue if !fnValue.Call([]reflect.Value{item})[0].Bool() { break } output.Send(item) } // hit the toggle, close the channel output.Close() // drop any extra messages for { _, ok := inputValue.Recv() if !ok { break } } }() return output.Interface() }
func evalBuiltinMakeExpr(ctx *Ctx, call *CallExpr, env *Env) ([]reflect.Value, error) { resT := call.KnownType()[0] length, capacity := 0, 0 var err error if len(call.Args) > 1 { if length, err = evalInteger(ctx, call.Args[1].(Expr), env); err != nil { return nil, err } } if len(call.Args) > 2 { if capacity, err = evalInteger(ctx, call.Args[2].(Expr), env); err != nil { return nil, err } } var res reflect.Value switch resT.Kind() { case reflect.Slice: res = reflect.MakeSlice(resT, length, capacity) case reflect.Map: res = reflect.MakeMap(resT) case reflect.Chan: res = reflect.MakeChan(resT, length) default: panic(dytc("make(bad type)")) } return []reflect.Value{res}, nil }
// FlattenChan is of type: func(input chan []T) chan T. // Takes a chan of arrays, and concatenates them together, putting each element // onto the output chan. After input is closed, output is also closed. If input // is chan T instead of type chan []T, then this is a no-op. func FlattenChan(input interface{}) interface{} { inputValue := reflect.ValueOf(input) if inputValue.Kind() != reflect.Chan { panic(fmt.Sprintf("FlattenChan called on invalid type: %s", inputValue.Type())) } elemType := inputValue.Type().Elem() if elemType.Kind() != reflect.Array && elemType.Kind() != reflect.Slice { return input } outputType := reflect.ChanOf(reflect.BothDir, elemType.Elem()) output := reflect.MakeChan(outputType, 0) go func() { for { value, ok := inputValue.Recv() if !ok { break } for i := 0; i < value.Len(); i++ { output.Send(value.Index(i)) } } output.Close() }() return output.Interface() }
func chanOfUnknown() { // Unknown channel direction: assume all three. // MakeChan only works on the bi-di channel type. t := reflect.ChanOf(unknownDir, reflect.TypeOf(&a)) print(reflect.Zero(t).Interface()) // @types <-chan *int | chan<- *int | chan *int print(reflect.MakeChan(t, 0).Interface()) // @types chan *int }
// Reset sets all elements of the object pointed to // by resultRef to their default or zero values. // But it works different from simply zeroing out everything, // here are the exceptions: // If resultRef is a pointer to a pointer, then // the pointed to pointer will be reset to a new instance // If resultRef is a pointer to a map, then the map // will be reset to a new empty one. // All other types pointed to by resultRef will be set // to their default zero values. func Reset(resultRef interface{}) { ptr := reflect.ValueOf(resultRef) if ptr.Kind() != reflect.Ptr { panic(fmt.Errorf("reflection.Reset(): resultRef must be a pointer, got %T", resultRef)) } val := ptr.Elem() switch val.Kind() { case reflect.Ptr: // If resultRef is a pointer to a pointer, // set the pointer to a new instance // of the pointed to type val.Set(reflect.New(val.Type().Elem())) case reflect.Map: // If resultRef is a pointer to a map, // set make an empty new map val.Set(reflect.MakeChan(val.Type(), 0)) case reflect.Struct: SetStructZero(val) default: val.Set(reflect.Zero(val.Type())) } }
func makeChan(typ reflect.Type, buffer ...int) interface{} { n := 0 if len(buffer) > 0 { n = buffer[0] } return &qlang.Chan{Data: reflect.MakeChan(typ, n)} }
// makeWorkerChans makes a buffered channel of the specified type func makeWorkerChans(t reflect.Type) (chan []reflect.Value, reflect.Value) { // display(reflect.TypeOf([]reflect.Value{})) // job := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(&channeller{})), 100) // job := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf([]reflect.Value{})), 100) job := make(chan []reflect.Value) res := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, t), 100) return job, res }
func Mkchan(typ interface{}, buffer ...int) *qlang.Chan { n := 0 if len(buffer) > 0 { n = buffer[0] } t := reflect.ChanOf(reflect.BothDir, types.Reflect(typ)) return &qlang.Chan{Data: reflect.MakeChan(t, n)} }
func makeOutputChan(o Output) reflect.Value { output := reflect.ValueOf(o) channel := reflect.MakeChan(output.Elem().Type(), 0) output.Elem().Set(channel) return channel }
func Test_InjectorSet(t *testing.T) { injector := inject.New() typ := reflect.TypeOf("string") typSend := reflect.ChanOf(reflect.SendDir, typ) typRecv := reflect.ChanOf(reflect.RecvDir, typ) // instantiating unidirectional channels is not possible using reflect // http://golang.org/src/pkg/reflect/value.go?s=60463:60504#L2064 chanRecv := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0) chanSend := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, typ), 0) injector.Set(typSend, chanSend) injector.Set(typRecv, chanRecv) expect(t, injector.Get(typSend).IsValid(), true) expect(t, injector.Get(typRecv).IsValid(), true) expect(t, injector.Get(chanSend.Type()).IsValid(), false) }
func (node *Node) MakeChan(name string, size int) reflect.Value { for i, argName := range node.argNames { if argName == name { argType := node.argTypes[i] return reflect.MakeChan(argType, size) } } panic("Argument not found.") }
// Make makes a channel from the parameters in ChannelDescriptor struct. func (c *ChannelDescriptor) Make(both bool) reflect.Value { dir := c.Dir if both { dir = reflect.BothDir } elem := types.MakeNew(c.TypeName, c.Size) typ := reflect.ChanOf(dir, elem.Type()) return reflect.MakeChan(typ, c.Size) }
func newSubscription(typ reflect.Type, unsubscribe func(*Subscription)) *Subscription { sub := &Subscription{ typ: typ, channel: reflect.MakeChan(typ, 0).Interface(), sleep: make(chan struct{}, 1), unsubscribe: unsubscribe, } go sub.loop() return sub }
// Parses str into a chan of typeOfElem. // Returns a pointer to a channel of type typeOfElem with a buffer size parsed from str. // Implements tags.ChanMaker func (valueMaker) MakeChan(str string, typeOfElem reflect.Type) (bool, uintptr, error) { i, err := strconv.Atoi(str) if err != nil { return false, 0, errors.New(fmt.Sprintf("failed to parse channel buffer capacity: %s", err.Error())) } c := reflect.MakeChan(typeOfElem, i) return true, c.Pointer(), nil }
// invokeMethod sends the specified RPC asynchronously and returns a // channel which receives the reply struct when the call is // complete. Returns a channel of the same type as "reply". func (db *LocalDB) invokeMethod(method string, args, reply interface{}) interface{} { chanVal := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(reply)), 1) replyVal := reflect.ValueOf(reply) reflect.ValueOf(db.rng).MethodByName(method).Call([]reflect.Value{ reflect.ValueOf(args), replyVal, }) chanVal.Send(replyVal) return chanVal.Interface() }
func chanOfBoth() { t := reflect.ChanOf(reflect.BothDir, reflect.TypeOf(&a)) print(reflect.Zero(t).Interface()) // @types <-chan *int | chan<- *int | chan *int ch := reflect.MakeChan(t, 0) print(ch.Interface().(chan *int)) // @pointsto <alloc in reflect.MakeChan> ch.Send(reflect.ValueOf(&b)) ch.Interface().(chan *int) <- &a r, _ := ch.Recv() print(r.Interface().(*int)) // @pointsto main.a | main.b print(<-ch.Interface().(chan *int)) // @pointsto main.a | main.b }
func sendSlice(slice interface{}) (channel interface{}) { sliceValue := reflect.ValueOf(slice) chanType := reflect.ChanOf(reflect.BothDir, sliceValue.Type().Elem()) chanValue := reflect.MakeChan(chanType, 0) go func() { for i := 0; i < sliceValue.Len(); i++ { chanValue.Send(sliceValue.Index(i)) } chanValue.Close() }() return chanValue.Interface() }
func (d *Dataset) SetupShard(n int) { ctype := reflect.ChanOf(reflect.BothDir, d.Type) for i := 0; i < n; i++ { ds := &DatasetShard{ Id: i, Parent: d, WriteChan: reflect.MakeChan(ctype, 0), } // println("created shard", ds.Name()) d.Shards = append(d.Shards, ds) } }
func NewOutChan(dec *Decoder, typ interface{}, buffer int) (ch <-chan interface{}) { t_ch := &reflect.MakeChan(reflect.Type(typ), buffer-1) p := t_ch.(unsafe.Pointer) ch = *p.(*chan interface{}) go func() { var err error for err != nil { i := &reflect.New(reflect.Type(typ)) err = dec.Decode(i) ch <- i.(unsafe.Pointer) } }() }
func pMapChan(dataChan interface{}, f interface{}) (resultChan interface{}) { fType := reflect.TypeOf(f) fRetType := fType.Out(0) dataChanType := reflect.TypeOf(dataChan) dataChanElemType := dataChanType.Elem() inChans := make([]reflect.Value, cpus) outChans := make([]reflect.Value, cpus) for i := 0; i < cpus; i++ { inChans[i] = reflect.MakeChan(reflect.ChanOf(reflect.BothDir, dataChanElemType), cpus) outChans[i] = reflect.MakeChan(reflect.ChanOf(reflect.BothDir, fRetType), cpus) go pMapChanInt(inChans[i], f, outChans[i]) } go pMapFeedInChans(dataChan, inChans) resultChanValue := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, fRetType), 0) resultChan = resultChanValue.Interface() go pMapDrainOutChans(outChans, resultChanValue) return }