summaryrefslogtreecommitdiffhomepage
path: root/pkg/fdchannel
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2020-11-13 01:52:59 -0800
committergVisor bot <gvisor-bot@google.com>2020-11-13 01:56:23 -0800
commit280cf46874cd8f4bd4fa16125aa6c0914b888deb (patch)
tree2b11e9fc37f101109e4d65187246205139c87c0b /pkg/fdchannel
parente869e2c7cddca0337b6dfb28584b05ee1b225a7f (diff)
Minor fdchannel fixes.
- Don't close fdchannel.Endpoint.sockfd in Shutdown(), while it still may be in use. - Don't call runtime.enter/exitsyscall from RecvFDNonblock(). PiperOrigin-RevId: 342221770
Diffstat (limited to 'pkg/fdchannel')
-rw-r--r--pkg/fdchannel/fdchannel_unsafe.go39
1 files changed, 18 insertions, 21 deletions
diff --git a/pkg/fdchannel/fdchannel_unsafe.go b/pkg/fdchannel/fdchannel_unsafe.go
index 367235be5..b253a8fdd 100644
--- a/pkg/fdchannel/fdchannel_unsafe.go
+++ b/pkg/fdchannel/fdchannel_unsafe.go
@@ -21,7 +21,6 @@ package fdchannel
import (
"fmt"
"reflect"
- "sync/atomic"
"syscall"
"unsafe"
)
@@ -41,7 +40,7 @@ func NewConnectedSockets() ([2]int, error) {
//
// Endpoint is not copyable or movable by value.
type Endpoint struct {
- sockfd int32 // accessed using atomic memory operations
+ sockfd int32
msghdr syscall.Msghdr
cmsg *syscall.Cmsghdr // followed by sizeofInt32 bytes of data
}
@@ -54,10 +53,10 @@ func (ep *Endpoint) Init(sockfd int) {
// sendmsg+recvmsg for a zero-length datagram is slightly faster than
// sendmsg+recvmsg for a single byte over a stream socket.
cmsgSlice := make([]byte, syscall.CmsgSpace(sizeofInt32))
- cmsgReflect := (*reflect.SliceHeader)((unsafe.Pointer)(&cmsgSlice))
+ cmsgReflect := (*reflect.SliceHeader)(unsafe.Pointer(&cmsgSlice))
ep.sockfd = int32(sockfd)
- ep.msghdr.Control = (*byte)((unsafe.Pointer)(cmsgReflect.Data))
- ep.cmsg = (*syscall.Cmsghdr)((unsafe.Pointer)(cmsgReflect.Data))
+ ep.msghdr.Control = (*byte)(unsafe.Pointer(cmsgReflect.Data))
+ ep.cmsg = (*syscall.Cmsghdr)(unsafe.Pointer(cmsgReflect.Data))
// ep.msghdr.Controllen and ep.cmsg.* are mutated by recvmsg(2), so they're
// set before calling sendmsg/recvmsg.
}
@@ -73,12 +72,8 @@ func NewEndpoint(sockfd int) *Endpoint {
// Destroy releases resources owned by ep. No other Endpoint methods may be
// called after Destroy.
func (ep *Endpoint) Destroy() {
- // These need not use sync/atomic since there must not be any concurrent
- // calls to Endpoint methods.
- if ep.sockfd >= 0 {
- syscall.Close(int(ep.sockfd))
- ep.sockfd = -1
- }
+ syscall.Close(int(ep.sockfd))
+ ep.sockfd = -1
}
// Shutdown causes concurrent and future calls to ep.SendFD(), ep.RecvFD(), and
@@ -88,10 +83,7 @@ func (ep *Endpoint) Destroy() {
// Shutdown is the only Endpoint method that may be called concurrently with
// other methods.
func (ep *Endpoint) Shutdown() {
- if sockfd := int(atomic.SwapInt32(&ep.sockfd, -1)); sockfd >= 0 {
- syscall.Shutdown(sockfd, syscall.SHUT_RDWR)
- syscall.Close(sockfd)
- }
+ syscall.Shutdown(int(ep.sockfd), syscall.SHUT_RDWR)
}
// SendFD sends the open file description represented by the given file
@@ -103,7 +95,7 @@ func (ep *Endpoint) SendFD(fd int) error {
ep.cmsg.SetLen(cmsgLen)
*ep.cmsgData() = int32(fd)
ep.msghdr.SetControllen(cmsgLen)
- _, _, e := syscall.Syscall(syscall.SYS_SENDMSG, uintptr(atomic.LoadInt32(&ep.sockfd)), uintptr((unsafe.Pointer)(&ep.msghdr)), 0)
+ _, _, e := syscall.Syscall(syscall.SYS_SENDMSG, uintptr(ep.sockfd), uintptr(unsafe.Pointer(&ep.msghdr)), 0)
if e != 0 {
return e
}
@@ -113,7 +105,7 @@ func (ep *Endpoint) SendFD(fd int) error {
// RecvFD receives an open file description from the connected Endpoint and
// returns a file descriptor representing it, owned by the caller.
func (ep *Endpoint) RecvFD() (int, error) {
- return ep.recvFD(0)
+ return ep.recvFD(false)
}
// RecvFDNonblock receives an open file description from the connected Endpoint
@@ -121,13 +113,18 @@ func (ep *Endpoint) RecvFD() (int, error) {
// are no pending receivable open file descriptions, RecvFDNonblock returns
// (<unspecified>, EAGAIN or EWOULDBLOCK).
func (ep *Endpoint) RecvFDNonblock() (int, error) {
- return ep.recvFD(syscall.MSG_DONTWAIT)
+ return ep.recvFD(true)
}
-func (ep *Endpoint) recvFD(flags uintptr) (int, error) {
+func (ep *Endpoint) recvFD(nonblock bool) (int, error) {
cmsgLen := syscall.CmsgLen(sizeofInt32)
ep.msghdr.SetControllen(cmsgLen)
- _, _, e := syscall.Syscall(syscall.SYS_RECVMSG, uintptr(atomic.LoadInt32(&ep.sockfd)), uintptr((unsafe.Pointer)(&ep.msghdr)), flags|syscall.MSG_TRUNC)
+ var e syscall.Errno
+ if nonblock {
+ _, _, e = syscall.RawSyscall(syscall.SYS_RECVMSG, uintptr(ep.sockfd), uintptr(unsafe.Pointer(&ep.msghdr)), syscall.MSG_TRUNC|syscall.MSG_DONTWAIT)
+ } else {
+ _, _, e = syscall.Syscall(syscall.SYS_RECVMSG, uintptr(ep.sockfd), uintptr(unsafe.Pointer(&ep.msghdr)), syscall.MSG_TRUNC)
+ }
if e != 0 {
return -1, e
}
@@ -142,5 +139,5 @@ func (ep *Endpoint) recvFD(flags uintptr) (int, error) {
func (ep *Endpoint) cmsgData() *int32 {
// syscall.CmsgLen(0) == syscall.cmsgAlignOf(syscall.SizeofCmsghdr)
- return (*int32)((unsafe.Pointer)(uintptr((unsafe.Pointer)(ep.cmsg)) + uintptr(syscall.CmsgLen(0))))
+ return (*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(ep.cmsg)) + uintptr(syscall.CmsgLen(0))))
}