@@ -1245,100 +1245,131 @@ elsewhere.
1245
1245
#### TCP
1246
1246
[ TCP ] : #tcp
1247
1247
1248
- For ` TcpStream ` , the changes are most easily expressed by giving the signatures directly:
1248
+ The current ` TcpStream ` struct will be pared back from where it is today to the
1249
+ following interface:
1249
1250
1250
1251
``` rust
1251
1252
// TcpStream, which contains both a reader and a writer
1252
1253
1253
1254
impl TcpStream {
1254
- fn connect <A : ToSocketAddr >(addr : A ) -> IoResult <TcpStreama >;
1255
- fn connect_deadline <A , D >(addr : A , deadline : D ) -> IoResult <TcpStreama > where
1256
- A : ToSocketAddr , D : IntoDeadline ;
1257
-
1258
- fn reader (& mut self ) -> & mut TcpReader ;
1259
- fn writer (& mut self ) -> & mut TcpWriter ;
1260
- fn split (self ) -> (TcpReader , TcpWriter );
1261
-
1262
- fn peer_addr (& mut self ) -> IoResult <SocketAddr >;
1263
- fn socket_addr (& mut self ) -> IoResult <SocketAddr >;
1264
- }
1265
-
1266
- impl Reader for TcpStream { ... }
1267
- impl Writer for TcpStream { ... }
1268
-
1269
- impl Reader for Deadlined <TcpStream > { ... }
1270
- impl Writer for Deadlined <TcpStream > { ... }
1271
-
1272
- // TcpReader
1273
-
1274
- impl Reader for TcpReader { ... }
1275
- impl Reader for Deadlined <TcpReader > { ... }
1276
-
1277
- impl TcpReader {
1278
- fn peer_addr (& mut self ) -> IoResult <SocketAddr >;
1279
- fn socket_addr (& mut self ) -> IoResult <SocketAddr >;
1280
-
1281
- fn shutdown_token (& mut self ) -> ShutdownToken ;
1255
+ fn connect <A : ToSocketAddrs >(addr : & A ) -> io :: Result <TcpStream >;
1256
+ fn peer_addr (& mut self ) -> io :: Result <SocketAddr >;
1257
+ fn socket_addr (& mut self ) -> io :: Result <SocketAddr >;
1258
+ fn shutdown (& mut self , how : Shutdown ) -> io :: Result <()>;
1259
+ fn duplicate (& self ) -> io :: Result <TcpStream >;
1282
1260
}
1283
1261
1284
- // TcpWriter
1285
-
1286
- impl Writer for TcpWriter { ... }
1287
- impl Writer for Deadlined <TcpWriter > { ... }
1262
+ impl Read for TcpStream { ... }
1263
+ impl Write for TcpStream { ... }
1264
+ impl <'a > Read for & 'a TcpStream { ... }
1265
+ impl <'a > Write for & 'a TcpStream { ... }
1266
+ #[cfg(unix)] impl AsRawFd for TcpStream { ... }
1267
+ #[cfg(windows)] impl AsRawSocket for TcpStream { ... }
1268
+ ```
1288
1269
1289
- impl TcpWriter {
1290
- fn peer_addr (& mut self ) -> IoResult <SocketAddr >;
1291
- fn socket_addr (& mut self ) -> IoResult <SocketAddr >;
1270
+ * ` clone ` has been replaced with a ` duplicate ` function. The implementation of
1271
+ ` duplicate ` will map to using ` dup ` on Unix platforms and
1272
+ ` WSADuplicateSocket ` on Windows platforms. The ` TcpStream ` itself will no
1273
+ longer be reference counted itself under the hood.
1274
+ * ` close_{read,write} ` are both removed in favor of binding the ` shutdown `
1275
+ function directly on sockets. This will map to the ` shutdown ` function on both
1276
+ Unix and Windows.
1277
+ * ` set_timeout ` has been removed for now (as well as other timeout-related
1278
+ functions). It is likely that this may come back soon as a binding to
1279
+ ` setsockopt ` to the ` SO_RCVTIMEO ` and ` SO_SNDTIMEO ` options. This RFC does not
1280
+ currently proposed adding them just yet, however.
1281
+ * Implementations of ` Read ` and ` Write ` are provided for ` &TcpStream ` . These
1282
+ implementations are not necessarily ergonomic to call (requires taking an
1283
+ explicit reference), but they express the ability to concurrently read and
1284
+ write from a ` TcpStream `
1285
+
1286
+ Various other options such as ` nodelay ` and ` keepalive ` will be left
1287
+ ` #[unstable] ` for now.
1288
+
1289
+ The ` TcpAcceptor ` struct will be removed and all functionality will be folded
1290
+ into the ` TcpListener ` structure. Specifically, this will be the resulting API:
1292
1291
1293
- fn shutdown_token (& mut self ) -> ShutdownToken ;
1292
+ ``` rust
1293
+ impl TcpListener {
1294
+ fn bind <A : ToSocketAddrs >(addr : & A ) -> io :: Result <TcpListener >;
1295
+ fn socket_addr (& mut self ) -> io :: Result <SocketAddr >;
1296
+ fn duplicate (& self ) -> io :: Result <TcpListener >;
1297
+ fn accept (& self ) -> io :: Result <(TcpStream , SocketAddr )>;
1298
+ fn incoming (& self ) -> Incoming ;
1294
1299
}
1295
1300
1296
- // ShutdownToken
1297
-
1298
- impl ShutdownToken {
1299
- fn shutdown (self );
1301
+ impl <'a > Iterator for Incoming <'a > {
1302
+ type Item = io :: Result <TcpStream >;
1303
+ ...
1300
1304
}
1301
-
1302
- impl Clone for ShutdownToken { ... }
1305
+ #[cfg(unix)] impl AsRawFd for TcpListener { ... }
1306
+ #[cfg(windows)] impl AsRawSocket for TcpListener { ... }
1303
1307
```
1304
1308
1305
- The idea is that a ` TcpStream ` provides both a reader and a writer,
1306
- and can be used directly as such, just as it can today. However, the
1307
- two sides can also be broken apart via the ` split ` method, which
1308
- allows them to be shipped off to separate threads. Moreover, each side
1309
- can yield a ` ShutdownToken ` , a ` Clone ` and ` Send ` value that can be
1310
- used to shut down that side of the socket, cancelling any in-progress
1311
- blocking operations, much like e.g. ` close_read ` does today.
1312
-
1313
- The implementation of the ` ShutdownToken ` infrastructure should ensure
1314
- that there is essentially no cost imposed when the feature is not used
1315
- -- in particular, if a ` ShutdownToken ` has not been requested, a
1316
- single ` read ` or ` write ` should correspond to a single syscall.
1317
-
1318
- For ` TcpListener ` , the only change is to rename ` socket_name ` to
1319
- ` socket_addr ` .
1320
-
1321
- For ` TcpAcceptor ` we will:
1322
-
1323
- * Add a ` socket_addr ` method.
1324
- * Possibly provide a convenience constructor for ` bind ` .
1325
- * Replace ` close_accept ` with ` cancel_token() ` .
1326
- * Remove ` Clone ` .
1327
- * Rename ` IncomingConnecitons ` to ` Incoming ` .
1309
+ Some major changes from today's API include:
1310
+
1311
+ * The static distinction between ` TcpAcceptor ` and ` TcpListener ` has been
1312
+ removed (more on this in the [ socket] [ Sockets ] section).
1313
+ * The ` clone ` functionality has been removed in favor of ` duplicate ` (same
1314
+ caveats as ` TcpStream ` ).
1315
+ * The ` close_accept ` functionality is removed entirely. This is not currently
1316
+ implemented via ` shutdown ` (not supported well across platforms) and is
1317
+ instead implemented via ` select ` . This functionality can return at a later
1318
+ date with a more robust interface.
1319
+ * The ` set_timeout ` functionality has also been removed in favor of returning at
1320
+ a later date in a more robust fashion with ` select ` .
1321
+ * The ` accept ` function no longer takes ` &mut self ` and returns ` SocketAddr ` .
1322
+ The change in mutability is done to express that multiple ` accept ` calls can
1323
+ happen concurrently.
1324
+ * For convenience the iterator does not yield the ` SocketAddr ` from ` accept ` .
1328
1325
1329
1326
#### UDP
1330
1327
[ UDP ] : #udp
1331
1328
1332
- The UDP infrastructure should change to use the new deadline
1333
- infrastructure, but should not provide ` Clone ` , ` ShutdownToken ` s, or a
1334
- reader/writer split. In addition:
1329
+ The UDP infrastructre will receive a similar face-lift as the TCP infrastructure
1330
+ will:
1335
1331
1336
- * ` recv_from ` should become ` recv ` .
1337
- * ` send_to ` should become ` send ` .
1338
- * ` socket_name ` should become ` socket_addr ` .
1332
+ ``` rust
1333
+ impl UdpSocket {
1334
+ fn bind <A : ToSocketAddrs >(addr : & A ) -> io :: Result <UdpSocket >;
1335
+ fn recv_from (& self , buf : & mut [u8 ]) -> io :: Result <(usize , SocketAddr )>;
1336
+ fn send_to <A : ToSocketAddrs >(& self , buf : & [u8 ], addr : & A ) -> io :: Result <usize >;
1337
+ fn socket_addr (& self ) -> io :: Result <SocketAddr >;
1338
+ fn duplicate (& self ) -> io :: Result <UdpSocket >;
1339
+ }
1340
+
1341
+ #[cfg(unix)] impl AsRawFd for UdpSocket { ... }
1342
+ #[cfg(windows)] impl AsRawSocket for UdpSocket { ... }
1343
+ ```
1339
1344
1340
- Methods like ` multicast ` and ` ttl ` are left as ` #[experimental] ` for
1341
- now (they are derived from libuv's design).
1345
+ Some important points of note are:
1346
+
1347
+ * The ` send ` and ` recv ` function take ` &self ` instead of ` &mut self ` to indicate
1348
+ that they may be called safely in concurrent contexts.
1349
+ * All configuration options such as ` multicast ` and ` ttl ` are left as
1350
+ ` #[unstable] ` for now.
1351
+ * All timeout support is removed. This may come back in the form of ` setsockopt `
1352
+ (as with TCP streams) or with a more general implementation of ` select ` .
1353
+ * ` clone ` functionality has been replaced with ` duplicate ` .
1354
+
1355
+ #### Sockets
1356
+ [ Sockets ] : #sockets
1357
+
1358
+ The current constructors for ` TcpStream ` , ` TcpListener ` , and ` UdpSocket ` are
1359
+ largely "convenience constructors" as they do not expose the underlying details
1360
+ that a socket can be configured before it is bound, connected, or listened on.
1361
+ One of the more frequent configuration options is ` SO_REUSEADDR ` which is set by
1362
+ default for ` TcpListener ` currently.
1363
+
1364
+ This RFC leaves it as an open question how best to implement this
1365
+ pre-configuration. The constructors today will likely remain no matter what as
1366
+ convenience constructors and a new structure would implement consuming methods
1367
+ to transform itself to each of the various ` TcpStream ` , ` TcpListener ` , and
1368
+ ` UdpSocket ` .
1369
+
1370
+ This RFC does, however, recommend not adding multiple constructors to the
1371
+ various types to set various configuration options. This pattern is best
1372
+ expressed via a flexible socket type to be added at a future date.
1342
1373
1343
1374
#### Addresses
1344
1375
[ Addresses ] : #addresses
0 commit comments