예제 #1
0
파일: chanreflect.go 프로젝트: 2722/lantern
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
}
예제 #2
0
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>
}
예제 #3
0
func MakeChannel(id string,
	fromClientStruct interface{},
	toClientStruct interface {})(fromClient unknownTypeChan,toclient unknownTypeChan) {

	fromClient=reflect.MakeChan(fromClientStruct,1)
	toclient=reflect.MakeChan(toClientStruct,1)


}
예제 #4
0
파일: channel.go 프로젝트: vuleetu/misc
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()
}
예제 #5
0
파일: local_db.go 프로젝트: hahan/cockroach
// 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()
}
예제 #6
0
// 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()
}
예제 #7
0
// 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()
}
예제 #8
0
// 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()
}
예제 #9
0
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
}
예제 #10
0
// 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()
}
예제 #11
0
// 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()
}
예제 #12
0
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
}
예제 #13
0
// 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()
}
예제 #14
0
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
}
예제 #15
0
// 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()))
	}
}
예제 #16
0
파일: chan.go 프로젝트: ttthzy/qlang
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)}
}
예제 #17
0
// 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
}
예제 #18
0
파일: chan.go 프로젝트: ttthzy/qlang
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)}
}
예제 #19
0
파일: junction.go 프로젝트: toshaf/junction
func makeOutputChan(o Output) reflect.Value {
	output := reflect.ValueOf(o)

	channel := reflect.MakeChan(output.Elem().Type(), 0)

	output.Elem().Set(channel)

	return channel
}
예제 #20
0
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)
}
예제 #21
0
파일: glow.go 프로젝트: johnnylee/glow
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.")
}
예제 #22
0
// 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)
}
예제 #23
0
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
}
예제 #24
0
// 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
}
예제 #25
0
// 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()
}
예제 #26
0
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
}
예제 #27
0
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()
}
예제 #28
0
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)
	}
}
예제 #29
0
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)
		}
	}()
}
예제 #30
0
파일: func.go 프로젝트: benashford/go-func
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
}