Skip to content

Commit db4e8da

Browse files
committed
---
yaml --- r: 154610 b: refs/heads/try2 c: c301db2 h: refs/heads/master v: v3
1 parent 0163f0b commit db4e8da

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
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 7441d4f3f33b4cc21912ff9a3b495f62abc3362e
8+
refs/heads/try2: c301db20a40d63ee330956a97102c3e566475f75
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

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

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

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

531545
while !self.inner.closed.load(atomics::SeqCst) {
@@ -545,6 +559,26 @@ impl TcpAcceptor {
545559

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

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

0 commit comments

Comments
 (0)