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