-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add function to enumerate devices #208
base: develop
Are you sure you want to change the base?
Conversation
src/node/mod.rs
Outdated
@@ -380,3 +380,21 @@ pub fn dev_path(dev: dev_t, ty: NodeType) -> io::Result<PathBuf> { | |||
), | |||
)) | |||
} | |||
|
|||
/// Returns a Vector with all DRM Nodes we managed to find. There might be duplicates. | |||
pub fn drm_get_devices() -> Result<Vec<DrmNode>, io::Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this instead return impl Iterator<Item = io::Result<DrmNode>>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what would be the best approach here.
We can have IO Errors only by failing to open/read the /dev
directory.
For the devices themselves, we will only get errors if they aren't DRM devices, which should be the case for the majority of stuff in /dev
.
Would iterator improve anything in regards to the error handling?
Also, sorry if my answers are a bit confusing. I'm quite new to Rust, so I might be missing the big-picture on how to better handle errors/iterators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have IO Errors only by failing to open/read the
/dev
directory.
That could be handled with:
io::Result<impl Iterator<Item = io::Result<DrmNode>>>
For the devices themselves, we will only get errors if they aren't DRM devices, which should be the case for the majority of stuff in
/dev
.
And as just mentioned below, drmGetDevices2()
skips errors while opening sub-devices, so we might as well return an iterator over DrmNode
directly:
io::Result<impl Iterator<Item = DrmNode>>
For the devices themselves, we will only get errors if they aren't DRM devices, which should be the case for the majority of stuff in
/dev
.
And as below, on most platforms except FreeBSD we should be reading /dev/dri
.
Also, sorry if my answers are a bit confusing. I'm quite new to Rust, so I might be missing the big-picture on how to better handle errors/iterators.
No worries, I think everyone is happy to educate new contributors on Rust as well as describing the "Rust style" used in drm-rs (as much as we're still discovering what that's supposed to be).
Regarding the drm_get_devices()
function name (based on drmGetDevices(2)()
), I'd drop the drm_
prefix since we're already in the drm
crate (i.e. a fully qualified call would look like drm::node::drm_get_devices()
which is somewhat superfluous) and then also drop the get_
prefix because of the no get_
prefix convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the feedback, it's highly appreciated.
I pushed the changes with everything you suggested. Do you mind to give another look?
src/node/mod.rs
Outdated
let mut devices: Vec<DrmNode> = vec![]; | ||
|
||
fs::read_dir("/dev")? | ||
.for_each(|entry| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making this a .map().collect()
rather than a side-effecting for_each()
? If that, use regular control flow with for entry in fs::read_dir(..)? { .. }
.
The .collect()
can be dropped if using @notgull's suggestion to return an iterator instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't we need to filter the results in some way if we use .map()
? Asking as we check all devices and likely a lot of them aren't DRM devices, so we need to skip them. This validation is done right now by calling DrmNode::from_path()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such filtering can be implemented by a .filter_map()
, but I'm hesitant to stat()
every device on the system to see if it is a DRM device.
Since drmGetDevices2()
was requested, I expected this feature to be built after that function. While it does also appear to ignore any error from processing individual devices, this function does open DRM_DIR_NAME
which is /dev/dri
on every platform except FreeBSD where it is /dev
. This way we don't have to stat()
devices that we know won't be DRM devices in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey thanks for the pointers. I somehow completely missed the fact that DRM_DIR_NAME
was different in certain platforms. I will update the code to also use /dev/dri
for all platforms except FreeBSD.
Co-authored-by: John Nunley <[email protected]>
Co-authored-by: Marijn Suijten <[email protected]>
Adds a basic DRM Listing functionality.
Please note that, different from libDRM, we don't process the devices to include bus information or anything else. We also don't de-duplicate devices like libDRM does, so duplicates might occur.
This change addresses #207