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 }