github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/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 func (fd *FD) Read(p []byte) (int, error) { 134 if err := fd.readLock(); err != nil { 135 return 0, err 136 } 137 defer fd.readUnlock() 138 if len(p) == 0 { 139 // If the caller wanted a zero byte read, return immediately 140 // without trying (but after acquiring the readLock). 141 // Otherwise syscall.Read returns 0, nil which looks like 142 // io.EOF. 143 // TODO(bradfitz): make it wait for readability? (Issue 15735) 144 return 0, nil 145 } 146 if err := fd.pd.prepareRead(fd.isFile); err != nil { 147 return 0, err 148 } 149 if fd.IsStream && len(p) > maxRW { 150 p = p[:maxRW] 151 } 152 for { 153 n, err := syscall.Read(fd.Sysfd, p) 154 if err != nil { 155 n = 0 156 if err == syscall.EAGAIN && fd.pd.pollable() { 157 if err = fd.pd.waitRead(fd.isFile); err == nil { 158 continue 159 } 160 } 161 162 // On MacOS we can see EINTR here if the user 163 // pressed ^Z. See issue #22838. 164 if runtime.GOOS == "darwin" && err == syscall.EINTR { 165 continue 166 } 167 } 168 err = fd.eofError(n, err) 169 return n, err 170 } 171 } 172 173 // Pread wraps the pread system call. 174 func (fd *FD) Pread(p []byte, off int64) (int, error) { 175 // Call incref, not readLock, because since pread specifies the 176 // offset it is independent from other reads. 177 // Similarly, using the poller doesn't make sense for pread. 178 if err := fd.incref(); err != nil { 179 return 0, err 180 } 181 if fd.IsStream && len(p) > maxRW { 182 p = p[:maxRW] 183 } 184 n, err := syscall.Pread(fd.Sysfd, p, off) 185 if err != nil { 186 n = 0 187 } 188 fd.decref() 189 err = fd.eofError(n, err) 190 return n, err 191 } 192 193 // ReadFrom wraps the recvfrom network call. 194 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) { 195 if err := fd.readLock(); err != nil { 196 return 0, nil, err 197 } 198 defer fd.readUnlock() 199 if err := fd.pd.prepareRead(fd.isFile); err != nil { 200 return 0, nil, err 201 } 202 for { 203 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0) 204 if err != nil { 205 n = 0 206 if err == syscall.EAGAIN && fd.pd.pollable() { 207 if err = fd.pd.waitRead(fd.isFile); err == nil { 208 continue 209 } 210 } 211 } 212 err = fd.eofError(n, err) 213 return n, sa, err 214 } 215 } 216 217 // ReadMsg wraps the recvmsg network call. 218 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 219 if err := fd.readLock(); err != nil { 220 return 0, 0, 0, nil, err 221 } 222 defer fd.readUnlock() 223 if err := fd.pd.prepareRead(fd.isFile); err != nil { 224 return 0, 0, 0, nil, err 225 } 226 for { 227 n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0) 228 if err != nil { 229 // TODO(dfc) should n and oobn be set to 0 230 if err == syscall.EAGAIN && fd.pd.pollable() { 231 if err = fd.pd.waitRead(fd.isFile); err == nil { 232 continue 233 } 234 } 235 } 236 err = fd.eofError(n, err) 237 return n, oobn, flags, sa, err 238 } 239 } 240 241 // Write implements io.Writer. 242 func (fd *FD) Write(p []byte) (int, error) { 243 if err := fd.writeLock(); err != nil { 244 return 0, err 245 } 246 defer fd.writeUnlock() 247 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 248 return 0, err 249 } 250 var nn int 251 for { 252 max := len(p) 253 if fd.IsStream && max-nn > maxRW { 254 max = nn + maxRW 255 } 256 n, err := syscall.Write(fd.Sysfd, p[nn:max]) 257 if n > 0 { 258 nn += n 259 } 260 if nn == len(p) { 261 return nn, err 262 } 263 if err == syscall.EAGAIN && fd.pd.pollable() { 264 if err = fd.pd.waitWrite(fd.isFile); err == nil { 265 continue 266 } 267 } 268 if err != nil { 269 return nn, err 270 } 271 if n == 0 { 272 return nn, io.ErrUnexpectedEOF 273 } 274 } 275 } 276 277 // Pwrite wraps the pwrite system call. 278 func (fd *FD) Pwrite(p []byte, off int64) (int, error) { 279 // Call incref, not writeLock, because since pwrite specifies the 280 // offset it is independent from other writes. 281 // Similarly, using the poller doesn't make sense for pwrite. 282 if err := fd.incref(); err != nil { 283 return 0, err 284 } 285 defer fd.decref() 286 var nn int 287 for { 288 max := len(p) 289 if fd.IsStream && max-nn > maxRW { 290 max = nn + maxRW 291 } 292 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn)) 293 if n > 0 { 294 nn += n 295 } 296 if nn == len(p) { 297 return nn, err 298 } 299 if err != nil { 300 return nn, err 301 } 302 if n == 0 { 303 return nn, io.ErrUnexpectedEOF 304 } 305 } 306 } 307 308 // WriteTo wraps the sendto network call. 309 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) { 310 if err := fd.writeLock(); err != nil { 311 return 0, err 312 } 313 defer fd.writeUnlock() 314 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 315 return 0, err 316 } 317 for { 318 err := syscall.Sendto(fd.Sysfd, p, 0, sa) 319 if err == syscall.EAGAIN && fd.pd.pollable() { 320 if err = fd.pd.waitWrite(fd.isFile); err == nil { 321 continue 322 } 323 } 324 if err != nil { 325 return 0, err 326 } 327 return len(p), nil 328 } 329 } 330 331 // WriteMsg wraps the sendmsg network call. 332 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 333 if err := fd.writeLock(); err != nil { 334 return 0, 0, err 335 } 336 defer fd.writeUnlock() 337 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 338 return 0, 0, err 339 } 340 for { 341 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0) 342 if err == syscall.EAGAIN && fd.pd.pollable() { 343 if err = fd.pd.waitWrite(fd.isFile); err == nil { 344 continue 345 } 346 } 347 if err != nil { 348 return n, 0, err 349 } 350 return n, len(oob), err 351 } 352 } 353 354 // Accept wraps the accept network call. 355 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) { 356 if err := fd.readLock(); err != nil { 357 return -1, nil, "", err 358 } 359 defer fd.readUnlock() 360 361 if err := fd.pd.prepareRead(fd.isFile); err != nil { 362 return -1, nil, "", err 363 } 364 for { 365 s, rsa, errcall, err := accept(fd.Sysfd) 366 if err == nil { 367 return s, rsa, "", err 368 } 369 switch err { 370 case syscall.EAGAIN: 371 if fd.pd.pollable() { 372 if err = fd.pd.waitRead(fd.isFile); err == nil { 373 continue 374 } 375 } 376 case syscall.ECONNABORTED: 377 // This means that a socket on the listen 378 // queue was closed before we Accept()ed it; 379 // it's a silly error, so try again. 380 continue 381 } 382 return -1, nil, errcall, err 383 } 384 } 385 386 // Seek wraps syscall.Seek. 387 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 388 if err := fd.incref(); err != nil { 389 return 0, err 390 } 391 defer fd.decref() 392 return syscall.Seek(fd.Sysfd, offset, whence) 393 } 394 395 // ReadDirent wraps syscall.ReadDirent. 396 // We treat this like an ordinary system call rather than a call 397 // that tries to fill the buffer. 398 func (fd *FD) ReadDirent(buf []byte) (int, error) { 399 if err := fd.incref(); err != nil { 400 return 0, err 401 } 402 defer fd.decref() 403 for { 404 n, err := syscall.ReadDirent(fd.Sysfd, buf) 405 if err != nil { 406 n = 0 407 if err == syscall.EAGAIN && fd.pd.pollable() { 408 if err = fd.pd.waitRead(fd.isFile); err == nil { 409 continue 410 } 411 } 412 } 413 // Do not call eofError; caller does not expect to see io.EOF. 414 return n, err 415 } 416 } 417 418 // Fchdir wraps syscall.Fchdir. 419 func (fd *FD) Fchdir() error { 420 if err := fd.incref(); err != nil { 421 return err 422 } 423 defer fd.decref() 424 return syscall.Fchdir(fd.Sysfd) 425 } 426 427 // Fstat wraps syscall.Fstat 428 func (fd *FD) Fstat(s *syscall.Stat_t) error { 429 if err := fd.incref(); err != nil { 430 return err 431 } 432 defer fd.decref() 433 return syscall.Fstat(fd.Sysfd, s) 434 } 435 436 // On Unix variants only, expose the IO event for the net code. 437 438 // WaitWrite waits until data can be read from fd. 439 func (fd *FD) WaitWrite() error { 440 return fd.pd.waitWrite(fd.isFile) 441 } 442 443 // WriteOnce is for testing only. It makes a single write call. 444 func (fd *FD) WriteOnce(p []byte) (int, error) { 445 if err := fd.writeLock(); err != nil { 446 return 0, err 447 } 448 defer fd.writeUnlock() 449 return syscall.Write(fd.Sysfd, p) 450 } 451 452 // RawControl invokes the user-defined function f for a non-IO 453 // operation. 454 func (fd *FD) RawControl(f func(uintptr)) error { 455 if err := fd.incref(); err != nil { 456 return err 457 } 458 defer fd.decref() 459 f(uintptr(fd.Sysfd)) 460 return nil 461 } 462 463 // RawRead invokes the user-defined function f for a read operation. 464 func (fd *FD) RawRead(f func(uintptr) bool) error { 465 if err := fd.readLock(); err != nil { 466 return err 467 } 468 defer fd.readUnlock() 469 if err := fd.pd.prepareRead(fd.isFile); err != nil { 470 return err 471 } 472 for { 473 if f(uintptr(fd.Sysfd)) { 474 return nil 475 } 476 if err := fd.pd.waitRead(fd.isFile); err != nil { 477 return err 478 } 479 } 480 } 481 482 // RawWrite invokes the user-defined function f for a write operation. 483 func (fd *FD) RawWrite(f func(uintptr) bool) error { 484 if err := fd.writeLock(); err != nil { 485 return err 486 } 487 defer fd.writeUnlock() 488 if err := fd.pd.prepareWrite(fd.isFile); err != nil { 489 return err 490 } 491 for { 492 if f(uintptr(fd.Sysfd)) { 493 return nil 494 } 495 if err := fd.pd.waitWrite(fd.isFile); err != nil { 496 return err 497 } 498 } 499 }