1

I'm reverse engineering a Go binary and came across the function selectnbrecv. However, I don't understand the documentation. I'll appreciate it if someone can explain to me the context and operation of the function. Thanks!

Newbie
  • 591
  • 1
  • 5
  • 11

1 Answers1

1

It is the Go runtime internal implemetaion for non blocking receive from the channel:
When the channel has any events the selectnbrecv function returns true otherwise returns false (for nil channel returns false): It receives on channel and writes the received data to v (if &v is not nil, in which case received data is ignored.) If no data are available, returns false. Otherwise, if the channel is closed, zeros v and returns true. Otherwise, fills in v with a data and returns true.

// compiler implements
//
//  select {
//  case v = <-c:
//      ... foo
//  default:
//      ... bar
//  }
//
// as
//
//  if selectnbrecv(&v, c) {
//      ... foo
//  } else {
//      ... bar
//  }
//
func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected bool) {
    selected, _ = chanrecv(c, elem, false) // false for non blocking
    return
}
wasmup
  • 14,541
  • 6
  • 42
  • 58
  • This is exactly what the question links to. – Jonathan Hall Dec 12 '20 at 14:45
  • @wasmup By element you mean bytes of data? Also, there is a typo in the word "receive" on the first line of your response in case you wanna fix it :) – Newbie Dec 12 '20 at 15:17
  • Yes `data` (value of a specified element type), see new update. e.g. `int` type for `chan int`, ... – wasmup Dec 12 '20 at 15:18
  • 1
    @wasmup Thank you for the answer. I don't have enough reputation to upvote it. Sorry! – Newbie Dec 12 '20 at 16:56
  • @wasmup So I did some reading on the "select" part. Basically it's a `switch-case` thing as what to do in various cases, right? – Newbie Dec 14 '20 at 23:07
  • @wasmup I'm really struggling with the concept of "select" here. Since the return value is called "selected" and the type of reading is non-blocking, I'm thinking whenever there is data available, the channel is gonna be selected, i.e., the return value selected is true. In other words, does the word "select" refer to the channel? – Newbie Dec 15 '20 at 00:38
  • @Newbie Yes and yes. The compiler implements `select` using `if else` e.g. like `switch case`. When the channel has any events the `selectnbrecv` function returns `true` - `selected` is just a name to convey meaning, When the channel has any events: a call to `close(channel)` without data is also an event so this function returns `true` too. see the comments inside the code in my answer. – wasmup Dec 15 '20 at 03:02
  • @wasmup I went through the comments. I think the description https://golang.org/src/runtime/chan.go?s=20089:20153#L699 is equivalent to what you said. I sort of started with `chanrecv` which returns `bool` for both `received` and `selected`. The "channel close" event you emphasized I think is categorized as `selected=true, received=false`, right? Other than that I think `selected=true, received=true` represents data being present in the channel so the channel gets selected, `selected=false, received=true` doesn't make sense in non-blocking mode, and `selected=false, received=false` is trivial. – Newbie Dec 15 '20 at 06:43