github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/internal/poll/fd_unix.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     6  
     7  package poll
     8  
     9  import (
    10  	"io"
    11  	"runtime"
    12  	"syscall"
    13  )
    14  
    15  // FD is a file descriptor. The net and os packages use this type as a
    16  // field of a larger type representing a network connection or OS file.
    17  type FD struct {
    18  	// Lock sysfd and serialize access to Read and Write methods.
    19  	fdmu fdMutex
    20  
    21  	// System file descriptor. Immutable until Close.
    22  	Sysfd int
    23  
    24  	// I/O poller.
    25  	pd pollDesc
    26  
    27  	// Writev cache.
    28  	iovecs *[]syscall.Iovec
    29  
    30  	// Semaphore signaled when file is closed.
    31  	csema uint32
    32  
    33  	// Whether this is a streaming descriptor, as opposed to a
    34  	// packet-based descriptor like a UDP socket. Immutable.
    35  	IsStream bool
    36  
    37  	// Whether a zero byte read indicates EOF. This is false for a
    38  	// message based socket connection.
    39  	ZeroReadIsEOF bool
    40  
    41  	// Whether this is a file rather than a network socket.
    42  	isFile bool
    43  
    44  	// Whether this file has been set to blocking mode.
    45  	isBlocking bool
    46  }
    47  
    48  // Init initializes the FD. The Sysfd field should already be set.
    49  // This can be called multiple times on a single FD.
    50  // The net argument is a network name from the net package (e.g., "tcp"),
    51  // or "file".
    52  // Set pollable to true if fd should be managed by runtime netpoll.
    53  func (fd *FD) Init(net string, pollable bool) error {
    54  	// We don't actually care about the various network types.
    55  	if net == "file" {
    56  		fd.isFile = true
    57  	}
    58  	if !pollable {
    59  		fd.isBlocking = true
    60  		return nil
    61  	}
    62  	return fd.pd.init(fd)
    63  }
    64  
    65  // Destroy closes the file descriptor. This is called when there are
    66  // no remaining references.
    67  func (fd *FD) destroy() error {
    68  	// Poller may want to unregister fd in readiness notification mechanism,
    69  	// so this must be executed before CloseFunc.
    70  	fd.pd.close()
    71  	err := CloseFunc(fd.Sysfd)
    72  	fd.Sysfd = -1
    73  	runtime_Semrelease(&fd.csema)
    74  	return err
    75  }
    76  
    77  // Close closes the FD. The underlying file descriptor is closed by the
    78  // destroy method when there are no remaining references.
    79  func (fd *FD) Close() error {
    80  	if !fd.fdmu.increfAndClose() {
    81  		return errClosing(fd.isFile)
    82  	}
    83  
    84  	// Unblock any I/O.  Once it all unblocks and returns,
    85  	// so that it cannot be referring to fd.sysfd anymore,
    86  	// the final decref will close fd.sysfd. This should happen
    87  	// fairly quickly, since all the I/O is non-blocking, and any
    88  	// attempts to block in the pollDesc will return errClosing(fd.isFile).
    89  	fd.pd.evict()
    90  
    91  	// The call to decref will call destroy if there are no other
    92  	// references.
    93  	err := fd.decref()
    94  
    95  	// Wait until the descriptor is closed. If this was the only
    96  	// reference, it is already closed. Only wait if the file has
    97  	// not been set to blocking mode, as otherwise any current I/O
    98  	// may be blocking, and that would block the Close.
    99  	if !fd.isBlocking {
   100  		runtime_Semacquire(&fd.csema)
   101  	}
   102  
   103  	return err
   104  }
   105  
   106  // Shutdown wraps the shutdown network call.
   107  func (fd *FD) Shutdown(how int) error {
   108  	if err := fd.incref(); err != nil {
   109  		return err
   110  	}
   111  	defer fd.decref()
   112  	return syscall.Shutdown(fd.Sysfd, how)
   113  }
   114  
   115  // SetBlocking puts the file into blocking mode.
   116  func (fd *FD) SetBlocking() error {
   117  	if err := fd.incref(); err != nil {
   118  		return err
   119  	}
   120  	defer fd.decref()
   121  	fd.isBlocking = true
   122  	return syscall.SetNonblock(fd.Sysfd, false)
   123  }
   124  
   125  // Darwin and FreeBSD can't read or write 2GB+ files at a time,
   126  // even on 64-bit systems.
   127  // The same is true of socket implementations on many systems.
   128  // See golang.org/issue/7812 and golang.org/issue/16266.
   129  // Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
   130  const maxRW = 1 << 30
   131  
   132  // Read implements io.Reader.
   133  // 只读一次, 读多少返多少
   134  func (fd *FD) Read(p []byte) (int, error) {
   135  	if err := fd.readLock(); err != nil {
   136  		return 0, err
   137  	}
   138  	defer fd.readUnlock()
   139  	if len(p) == 0 {
   140  		// If the caller wanted a zero byte read, return immediately
   141  		// without trying (but after acquiring the readLock).
   142  		// Otherwise syscall.Read returns 0, nil which looks like
   143  		// io.EOF.
   144  		// TODO(bradfitz): make it wait for readability? (Issue 15735)
   145  		return 0, nil
   146  	}
   147  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   148  		return 0, err
   149  	}
   150  	if fd.IsStream && len(p) > maxRW {
   151  		p = p[:maxRW]
   152  	}
   153  	for {
   154  		n, err := syscall.Read(fd.Sysfd, p)
   155  		if err != nil {
   156  			n = 0
   157  			// fd关联到文件或socket且被标记为O_NONBLOCK(go的行为)且读会阻塞时返回EAGAIN或EWOULDBLOCK(在linux下EWOULDBLOCK是EAGAIN的alias), see `man 2 read`
   158  			if err == syscall.EAGAIN && fd.pd.pollable() {
   159  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   160  					continue
   161  				}
   162  			}
   163  
   164  			// On MacOS we can see EINTR here if the user
   165  			// pressed ^Z.  See issue #22838.
   166  			if runtime.GOOS == "darwin" && err == syscall.EINTR {
   167  				continue
   168  			}
   169  		}
   170  		err = fd.eofError(n, err)
   171  		return n, err
   172  	}
   173  }
   174  
   175  // Pread wraps the pread system call.
   176  func (fd *FD) Pread(p []byte, off int64) (int, error) {
   177  	// Call incref, not readLock, because since pread specifies the
   178  	// offset it is independent from other reads.
   179  	// Similarly, using the poller doesn't make sense for pread.
   180  	if err := fd.incref(); err != nil {
   181  		return 0, err
   182  	}
   183  	if fd.IsStream && len(p) > maxRW {
   184  		p = p[:maxRW]
   185  	}
   186  	n, err := syscall.Pread(fd.Sysfd, p, off)
   187  	if err != nil {
   188  		n = 0
   189  	}
   190  	fd.decref()
   191  	err = fd.eofError(n, err)
   192  	return n, err
   193  }
   194  
   195  // ReadFrom wraps the recvfrom network call.
   196  func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
   197  	if err := fd.readLock(); err != nil {
   198  		return 0, nil, err
   199  	}
   200  	defer fd.readUnlock()
   201  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   202  		return 0, nil, err
   203  	}
   204  	for {
   205  		n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
   206  		if err != nil {
   207  			n = 0
   208  			if err == syscall.EAGAIN && fd.pd.pollable() {
   209  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   210  					continue
   211  				}
   212  			}
   213  		}
   214  		err = fd.eofError(n, err)
   215  		return n, sa, err
   216  	}
   217  }
   218  
   219  // ReadMsg wraps the recvmsg network call.
   220  func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) {
   221  	if err := fd.readLock(); err != nil {
   222  		return 0, 0, 0, nil, err
   223  	}
   224  	defer fd.readUnlock()
   225  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   226  		return 0, 0, 0, nil, err
   227  	}
   228  	for {
   229  		n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
   230  		if err != nil {
   231  			// TODO(dfc) should n and oobn be set to 0
   232  			if err == syscall.EAGAIN && fd.pd.pollable() {
   233  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   234  					continue
   235  				}
   236  			}
   237  		}
   238  		err = fd.eofError(n, err)
   239  		return n, oobn, flags, sa, err
   240  	}
   241  }
   242  
   243  // Write implements io.Writer.
   244  func (fd *FD) Write(p []byte) (int, error) {
   245  	if err := fd.writeLock(); err != nil {
   246  		return 0, err
   247  	}
   248  	defer fd.writeUnlock()
   249  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   250  		return 0, err
   251  	}
   252  	var nn int
   253  	for {
   254  		max := len(p)
   255  		if fd.IsStream && max-nn > maxRW {
   256  			max = nn + maxRW
   257  		}
   258  		n, err := syscall.Write(fd.Sysfd, p[nn:max])
   259  		if n > 0 {
   260  			nn += n
   261  		}
   262  		if nn == len(p) {
   263  			return nn, err
   264  		}
   265  		if err == syscall.EAGAIN && fd.pd.pollable() {
   266  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   267  				continue
   268  			}
   269  		}
   270  		if err != nil {
   271  			return nn, err
   272  		}
   273  		if n == 0 {
   274  			return nn, io.ErrUnexpectedEOF
   275  		}
   276  	}
   277  }
   278  
   279  // Pwrite wraps the pwrite system call.
   280  func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
   281  	// Call incref, not writeLock, because since pwrite specifies the
   282  	// offset it is independent from other writes.
   283  	// Similarly, using the poller doesn't make sense for pwrite.
   284  	if err := fd.incref(); err != nil {
   285  		return 0, err
   286  	}
   287  	defer fd.decref()
   288  	var nn int
   289  	for {
   290  		max := len(p)
   291  		if fd.IsStream && max-nn > maxRW {
   292  			max = nn + maxRW
   293  		}
   294  		n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
   295  		if n > 0 {
   296  			nn += n
   297  		}
   298  		if nn == len(p) {
   299  			return nn, err
   300  		}
   301  		if err != nil {
   302  			return nn, err
   303  		}
   304  		if n == 0 {
   305  			return nn, io.ErrUnexpectedEOF
   306  		}
   307  	}
   308  }
   309  
   310  // WriteTo wraps the sendto network call.
   311  func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
   312  	if err := fd.writeLock(); err != nil {
   313  		return 0, err
   314  	}
   315  	defer fd.writeUnlock()
   316  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   317  		return 0, err
   318  	}
   319  	for {
   320  		err := syscall.Sendto(fd.Sysfd, p, 0, sa)
   321  		if err == syscall.EAGAIN && fd.pd.pollable() {
   322  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   323  				continue
   324  			}
   325  		}
   326  		if err != nil {
   327  			return 0, err
   328  		}
   329  		return len(p), nil
   330  	}
   331  }
   332  
   333  // WriteMsg wraps the sendmsg network call.
   334  func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
   335  	if err := fd.writeLock(); err != nil {
   336  		return 0, 0, err
   337  	}
   338  	defer fd.writeUnlock()
   339  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   340  		return 0, 0, err
   341  	}
   342  	for {
   343  		n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
   344  		if err == syscall.EAGAIN && fd.pd.pollable() {
   345  			if err = fd.pd.waitWrite(fd.isFile); err == nil {
   346  				continue
   347  			}
   348  		}
   349  		if err != nil {
   350  			return n, 0, err
   351  		}
   352  		return n, len(oob), err
   353  	}
   354  }
   355  
   356  // Accept wraps the accept network call.
   357  func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
   358  	if err := fd.readLock(); err != nil {
   359  		return -1, nil, "", err
   360  	}
   361  	defer fd.readUnlock()
   362  
   363  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   364  		return -1, nil, "", err
   365  	}
   366  	for {
   367  		s, rsa, errcall, err := accept(fd.Sysfd)
   368  		if err == nil {
   369  			return s, rsa, "", err
   370  		}
   371  		switch err {
   372  		case syscall.EAGAIN:
   373  			if fd.pd.pollable() {
   374  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   375  					continue
   376  				}
   377  			}
   378  		case syscall.ECONNABORTED:
   379  			// This means that a socket on the listen
   380  			// queue was closed before we Accept()ed it;
   381  			// it's a silly error, so try again.
   382  			continue
   383  		}
   384  		return -1, nil, errcall, err
   385  	}
   386  }
   387  
   388  // Seek wraps syscall.Seek.
   389  func (fd *FD) Seek(offset int64, whence int) (int64, error) {
   390  	if err := fd.incref(); err != nil {
   391  		return 0, err
   392  	}
   393  	defer fd.decref()
   394  	return syscall.Seek(fd.Sysfd, offset, whence)
   395  }
   396  
   397  // ReadDirent wraps syscall.ReadDirent.
   398  // We treat this like an ordinary system call rather than a call
   399  // that tries to fill the buffer.
   400  func (fd *FD) ReadDirent(buf []byte) (int, error) {
   401  	if err := fd.incref(); err != nil {
   402  		return 0, err
   403  	}
   404  	defer fd.decref()
   405  	for {
   406  		n, err := syscall.ReadDirent(fd.Sysfd, buf)
   407  		if err != nil {
   408  			n = 0
   409  			if err == syscall.EAGAIN && fd.pd.pollable() {
   410  				if err = fd.pd.waitRead(fd.isFile); err == nil {
   411  					continue
   412  				}
   413  			}
   414  		}
   415  		// Do not call eofError; caller does not expect to see io.EOF.
   416  		return n, err
   417  	}
   418  }
   419  
   420  // Fchdir wraps syscall.Fchdir.
   421  func (fd *FD) Fchdir() error {
   422  	if err := fd.incref(); err != nil {
   423  		return err
   424  	}
   425  	defer fd.decref()
   426  	return syscall.Fchdir(fd.Sysfd)
   427  }
   428  
   429  // Fstat wraps syscall.Fstat
   430  func (fd *FD) Fstat(s *syscall.Stat_t) error {
   431  	if err := fd.incref(); err != nil {
   432  		return err
   433  	}
   434  	defer fd.decref()
   435  	return syscall.Fstat(fd.Sysfd, s)
   436  }
   437  
   438  // On Unix variants only, expose the IO event for the net code.
   439  
   440  // WaitWrite waits until data can be read from fd.
   441  func (fd *FD) WaitWrite() error {
   442  	return fd.pd.waitWrite(fd.isFile)
   443  }
   444  
   445  // WriteOnce is for testing only. It makes a single write call.
   446  func (fd *FD) WriteOnce(p []byte) (int, error) {
   447  	if err := fd.writeLock(); err != nil {
   448  		return 0, err
   449  	}
   450  	defer fd.writeUnlock()
   451  	return syscall.Write(fd.Sysfd, p)
   452  }
   453  
   454  // RawControl invokes the user-defined function f for a non-IO
   455  // operation.
   456  func (fd *FD) RawControl(f func(uintptr)) error {
   457  	if err := fd.incref(); err != nil {
   458  		return err
   459  	}
   460  	defer fd.decref()
   461  	f(uintptr(fd.Sysfd))
   462  	return nil
   463  }
   464  
   465  // RawRead invokes the user-defined function f for a read operation.
   466  func (fd *FD) RawRead(f func(uintptr) bool) error {
   467  	if err := fd.readLock(); err != nil {
   468  		return err
   469  	}
   470  	defer fd.readUnlock()
   471  	if err := fd.pd.prepareRead(fd.isFile); err != nil {
   472  		return err
   473  	}
   474  	for {
   475  		if f(uintptr(fd.Sysfd)) {
   476  			return nil
   477  		}
   478  		if err := fd.pd.waitRead(fd.isFile); err != nil {
   479  			return err
   480  		}
   481  	}
   482  }
   483  
   484  // RawWrite invokes the user-defined function f for a write operation.
   485  func (fd *FD) RawWrite(f func(uintptr) bool) error {
   486  	if err := fd.writeLock(); err != nil {
   487  		return err
   488  	}
   489  	defer fd.writeUnlock()
   490  	if err := fd.pd.prepareWrite(fd.isFile); err != nil {
   491  		return err
   492  	}
   493  	for {
   494  		if f(uintptr(fd.Sysfd)) {
   495  			return nil
   496  		}
   497  		if err := fd.pd.waitWrite(fd.isFile); err != nil {
   498  			return err
   499  		}
   500  	}
   501  }