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!
Asked
Active
Viewed 320 times
1

Newbie
- 591
- 1
- 5
- 11
-
2Hint: the nb in selectnbrecv stands for non-blocking. – Dec 12 '20 at 14:50
1 Answers
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
-
-
@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