Skip to content

Commit 11852b3

Browse files
committed
---
yaml --- r: 124279 b: refs/heads/try c: 85b1c0044ebab71f9c3535791426b10d300d96f3 h: refs/heads/master i: 124277: 368818b 124275: 8a78dd5 124271: 32c32ba v: v3
1 parent dc5c500 commit 11852b3

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 6c35d513cea468b30759b4f78becf28f11a123c0
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: afbcbbc77ffc6b10053bc543daf7d2e05d68cc01
5-
refs/heads/try: 65489a7ee8c5399c5eaf14c2ffb3b126384fe5ab
5+
refs/heads/try: 85b1c0044ebab71f9c3535791426b10d300d96f3
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libnative/io/net.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,20 @@ impl TcpAcceptor {
522522

523523
#[cfg(unix)]
524524
pub fn native_accept(&mut self) -> IoResult<TcpStream> {
525+
// In implementing accept, the two main concerns are dealing with
526+
// close_accept() and timeouts. The unix implementation is based on a
527+
// nonblocking accept plus a call to select(). Windows ends up having
528+
// an entirely separate implementation than unix, which is explained
529+
// below.
530+
//
531+
// To implement timeouts, all blocking is done via select() instead of
532+
// accept() by putting the socket in non-blocking mode. Because
533+
// select() takes a timeout argument, we just pass through the timeout
534+
// to select().
535+
//
536+
// To implement close_accept(), we have a self-pipe to ourselves which
537+
// is passed to select() along with the socket being accepted on. The
538+
// self-pipe is never written to unless close_accept() is called.
525539
let deadline = if self.deadline == 0 {None} else {Some(self.deadline)};
526540

527541
while !self.inner.closed.load(atomics::SeqCst) {
@@ -541,6 +555,26 @@ impl TcpAcceptor {
541555

542556
#[cfg(windows)]
543557
pub fn native_accept(&mut self) -> IoResult<TcpStream> {
558+
// Unlink unix, windows cannot invoke `select` on arbitrary file
559+
// descriptors like pipes, only sockets. Consequently, windows cannot
560+
// use the same implementation as unix for accept() when close_accept()
561+
// is considered.
562+
//
563+
// In order to implement close_accept() and timeouts, windows uses
564+
// event handles. An acceptor-specific abort event is created which
565+
// will only get set in close_accept(), and it will never be un-set.
566+
// Additionally, another acceptor-specific event is associated with the
567+
// FD_ACCEPT network event.
568+
//
569+
// These two events are then passed to WaitForMultipleEvents to see
570+
// which one triggers first, and the timeout passed to this function is
571+
// the local timeout for the acceptor.
572+
//
573+
// If the wait times out, then the accept timed out. If the wait
574+
// succeeds with the abort event, then we were closed, and if the wait
575+
// succeeds otherwise, then we do a nonblocking poll via `accept` to
576+
// see if we can accept a connection. The connection is candidate to be
577+
// stolen, so we do all of this in a loop as well.
544578
let events = [self.inner.abort.handle(), self.inner.accept.handle()];
545579

546580
while !self.inner.closed.load(atomics::SeqCst) {

0 commit comments

Comments
 (0)