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