<commit_before>package netchan

import "runtime"

// SelectRecv loops on multiple receivers until it gets a value, it will
// return nil, nil if block==false and there was nothing to receive
func SelectRecv(block bool, recvs []Receiver) (Receiver, interface{}) {
	for {
		for _, ch := range recvs {
			_, val, st := ch.Recv(false)
			if st == StatusOK {
				return ch, val
			}
		}
		if !block {
			return nil, nil
		}
		runtime.Gosched()
	}
}

// SelectSend loops on multiple senders and returns the first channel that
// was able to send or nil if block == false and nothing was sent.
func SelectSend(block bool, targets []Sender, val interface{}) Sender {
	for {
		for _, ch := range targets {
			st := ch.Send(false, val)
			if st == StatusOK {
				return ch
			}
		}
		if !block {
			return nil
		}
		runtime.Gosched()
	}
}<commit_msg>now Select uses reflect.Select, so it always block now<commit_after>package netchan

import "reflect"

// SelectRecv loops on multiple receivers until it gets a value,
// it blocks until a value is returned or all channels are closed.
// this function doesn't panic.
func SelectRecv(recvs []Receiver) (r Receiver, val interface{}) {
	defer func() {
		if recover() != nil {
			r = nil
			val = nil
		}
	}()
	cases := make([]reflect.SelectCase, len(recvs))
	for i, rch := range recvs {
		cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv}
		switch rch := rch.(type) {
		case Channel:
			cases[i].Chan = reflect.ValueOf(rch.r)
		case LocalReceiver:
			cases[i].Chan = reflect.ValueOf((<-chan interface{})(rch))
		default:
			panic("SelectRecv only supports Channel and/or LocalReceiver")
		}
	}
	i, v, ok := reflect.Select(cases)
	if ok {
		r = recvs[i]
		val = v.Interface()
		if val, ok := val.(*pkt); ok {
			return r, val.Value
		}
		return
	}
	return
}

// SelectSend loops on multiple senders and returns the first channel that
// was able to send.
// it returns the target that sent the value or returns nil if all channels were closed
// this function doesn't panic.
func SelectSend(targets []Sender, val interface{}) (sch Sender) {
	defer func() {
		if recover() != nil {
			sch = nil
		}
	}()
	cases := make([]reflect.SelectCase, len(targets))
	p := reflect.ValueOf(&pkt{Type: pktData, Value: val})
	for i, sch := range targets {
		cases[i] = reflect.SelectCase{Dir: reflect.SelectSend}
		switch sch := sch.(type) {
		case Channel:
			cases[i].Chan = reflect.ValueOf(sch.s)
			cases[i].Send = p
		case LocalSender:
			cases[i].Chan = reflect.ValueOf((chan<- interface{})(sch))
			cases[i].Send = reflect.ValueOf(val)
		default:
			panic("SelectSend only supports Channel and/or LocalSender")
		}
	}
	i, _, _ := reflect.Select(cases)
	return targets[i]
}
{'fraction_non_alphanumeric': 0.1290680473372781, 'fraction_numerical': 0.0, 'mean_word_length': 3.427168576104746, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7601961', 'n_tokens_mistral': 969, 'n_tokens_neox': 881, 'n_words': 300}