You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds an unsafe helper for wrapping an `AsRawFd` implementer in `AsFd`.
Which is needed with things like zmq until they update to use IO safety
traits: erickt/rust-zmq#361.
Copy file name to clipboardExpand all lines: doc/src/ch02-01-generic.md
+6-10
Original file line number
Diff line number
Diff line change
@@ -3,25 +3,21 @@ The `Generic` event source wraps a file descriptor ("fd") and fires its callback
3
3
4
4
For example on Linux, fd-based interfaces are available for GPIO, I2C, USB, UART, network interfaces, timers and many other systems. Integrating these into calloop starts with obtaining the appropriate fd, creating a `Generic` event source from it, and building up a more useful, abstracted event source around that. A detailed example of this is [given for ZeroMQ](ch04-00-a-full-example-zeromq.md).
5
5
6
-
You do not have to use a low-level fd either: any type that implements [`AsRawFd`](https://doc.rust-lang.org/beta/std/os/unix/io/trait.AsRawFd.html) can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement `AsRawFd` on it so that `Generic` can manage it in the event loop.
6
+
You do not have to use a low-level fd either: any type that implements [`AsFd`](https://doc.rust-lang.org/stable/std/os/fd/trait.AsFd.html) can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement `AsRawFd` on it so that `Generic` can manage it in the event loop.
7
7
8
8
## Creating a Generic source
9
9
10
10
Creating a `Generic` event source requires three things:
11
-
-The fd itself, of course, possibly in a wrapper type that implements `AsRawFd`
11
+
-An `OwnedFd` or a wrapper type that implements `AsFd`
12
12
- The ["interest"](api/calloop/struct.Interest.html) you have in this descriptor — this means, whether you want to generate events when the fd becomes readable, writeable, or both
13
13
- The ["mode"](api/calloop/enum.Mode.html) of event generation - level triggered or edge triggered
14
14
15
15
The easiest constructor to use is the [`new()`](api/calloop/generic/struct.Generic.html#method.new) method, but if you need control over the [associated error type](ch02-06-errors.md) there is also [`new_with_error()`](api/calloop/generic/struct.Generic.html#method.new_with_error).
16
16
17
-
## Ownership and AsRawFd wrappers
17
+
## Ownership and AsFd wrappers
18
18
19
-
It's important to remember that file descriptors by themselves have no concept of ownership attached to them in Rust — they are simply bare integers. Dropping them does not close the resource they refer to, and copying them does not carry information about how many there are.
19
+
Rust 1.63 introduced a concept of file descriptor ownership and borrowing through the `OwnedFd` and `BorrowedFd` types, which are also available on older Rust versions through the `io-lifetimes` crate. The `AsFd` trait provides a way to get a `BorrowedFd` corresponding to a file, socket, etc. while guaranteeing the fd will be valid for the lifetime of the `BorrowedFd`.
20
20
21
-
Typically (eg. in the standard library) they would be an underlying implementation detail of another type that *did* encode ownership somehow. This how you can manage them in any of your own integration code - use drop handlers, reference counting (if necessary) and general RAII principles in a wrapper type, and then implement `AsRawFd` to allow `Generic` to use it. The `Generic` source will take ownership of it, so it will be dropped when the `Generic` is.
21
+
Not all third party crates use `AsFd` yet, and may instead provide types implementing `AsRawFd`. ['AsFdWrapper'](api/calloop/generic/struct.AsFdWrapper.html) provides a way to adapt these types. To use this safely, ensure the `AsRawFd` implementation of the type it wraps returns a valid fd as long as the type exists. And to avoid an fd leak, it should ultimately be `close`d properly.
22
22
23
-
This means you need to do at least two things:
24
-
- follow the rules of the API you obtain the fd from
25
-
- wrap them in a type that manages ownership appropriately
26
-
27
-
For example, on Unix-like systems the [`UdpSocket`](https://doc.rust-lang.org/beta/std/net/struct.UdpSocket.html) contains a fd, and upon being dropped, `libc::close(fd)` is called on it. If you create a `Generic<UdpSocket>` then, it will be closed upon dropping it.
23
+
Safe types like `OwnedFd` and `BorrowedFd` should be preferred over `RawFd`s, and the use of `RawFd`s outside of implementing FFI shouldn't be necessary as libraries move to using the IO safe types and traits.
Copy file name to clipboardExpand all lines: doc/src/ch03-02-async-io-types.md
+2-2
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
> This section is about adapting blocking IO types for use with `async` Rust code, and powering that `async` code with Calloop. If you just want to add blocking IO types to your event loop and use Calloop's callback/composition-based design, you only need to wrap your blocking IO type in a [generic event source](api/calloop/generic/struct.Generic.html).
4
4
5
-
You may find that you need to write ordinary Rust `async` code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the [`AsRawFd`](https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsRawFd.html) trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using [Calloop's executor](api/calloop/futures/fn.executor.html).
5
+
You may find that you need to write ordinary Rust `async` code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the [`AsFd`](https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html) trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using [Calloop's executor](api/calloop/futures/fn.executor.html).
6
6
7
7
> ## Enable the `futures-io` feature!
8
8
>
@@ -65,4 +65,4 @@ Starting event loop. Use Ctrl-C to exit.
0 commit comments