Cgo: using syscall.Select

324 views
Skip to first unread message

Juliusz Chroboczek

unread,
May 16, 2018, 8:08:29 PM5/16/18
to golan...@googlegroups.com
I'm interfacing with a C library that expects to do its own I/O, but
wants to be called after a file descriptor is ready for read. My code
currently looks roughly like this:

var fdset syscall.FdSet
var bits = unsafe.Sizeof(fdset.Bits[0]) * 8
fdset.Bits[uintptr(fd)/bits] |= (1 << (fd % bits))
var ctv C.struct_timeval
C.gettimeout(&ctv)
tv := syscall.Timeval{int64(ctv.tv_sec), int64(ctv.tv_usec)}
n, err := syscall.Select(int(fd + 1), &fdset, nil, nil, &tv)
if n < 0 {
return err
}
rc, err := C.dostuff(fd)
if(rc < 0) {
return err
}

I'm bothered by two things:

- the way I access the syscall.FdSet feels like an unportable hack;
- I'd much rather hook into Go's scheduler then burn a thread on
sleeping in select.

Is the above the correct way to interface with the C library, or is
there a better way?

Ian Lance Taylor

unread,
May 16, 2018, 11:02:34 PM5/16/18
to Juliusz Chroboczek, golang-nuts
If you do this in Go, you should use golang.org/x/sys/unix package
rather than the syscall package. But since you have to call C anyhow,
I would suggest just doing it in C.

There isn't any way to hook into Go's scheduler for this. Go's
scheduler provides no mechanism for waiting for data without reading
the data.

Ian

Juliusz Chroboczek

unread,
May 17, 2018, 9:57:11 AM5/17/18
to Ian Lance Taylor, golang-nuts
> If you do this in Go, you should use golang.org/x/sys/unix package
> rather than the syscall package.

What's the advantage? (In this particular case, not in general.)

> But since you have to call C anyhow, I would suggest just doing it in C.

Yeah, I guess it's simpler.

> There isn't any way to hook into Go's scheduler for this. Go's
> scheduler provides no mechanism for waiting for data without reading
> the data.

I suppose it makes sense, the operation might be difficult to implement in
a hypothetical scheduler that's layered over mainframe-style async operations.

Thanks for your reply,

-- Juliusz

Ian Lance Taylor

unread,
May 17, 2018, 10:44:11 AM5/17/18
to Juliusz Chroboczek, golang-nuts
On Thu, May 17, 2018 at 9:56 AM, Juliusz Chroboczek <j...@irif.fr> wrote:
>> If you do this in Go, you should use golang.org/x/sys/unix package
>> rather than the syscall package.
>
> What's the advantage? (In this particular case, not in general.)

The advantage in this particular case is likely minimal. The main
advantage is portability. For example, Go runs on Solaris, but the
syscall package does not support syscall.Select on Solaris. The
golang.org/x/sys/unix package does.

Ian

Сергей Камардин

unread,
May 18, 2018, 12:57:27 AM5/18/18
to golang-nuts
You could also take a look at https://godoc.org/github.com/mailru/easygo/netpoll

четверг, 17 мая 2018 г., 3:08:29 UTC+3 пользователь Juliusz Chroboczek написал:

Juliusz Chroboczek

unread,
May 18, 2018, 7:52:27 PM5/18/18
to golan...@googlegroups.com
> You could also take a look
> at https://godoc.org/github.com/mailru/easygo/netpoll

I don't have a net.Conn, just a raw file descriptor.

-- Juliusz

Sergey Kamardin

unread,
May 19, 2018, 2:27:52 AM5/19/18
to golang-nuts
There are methods which are using raw file descriptors (such that https://godoc.org/github.com/mailru/easygo/netpoll#NewDesc).

суббота, 19 мая 2018 г., 2:52:27 UTC+3 пользователь Juliusz Chroboczek написал:
Reply all
Reply to author
Forward
0 new messages