Fixes a minor race condition in active_displays (#686)
Fixes a minor race condition in active_displays that might happen if a display is removed between the active_display_count and the CGGetActiveDisplayList. In that case the returned vec would be inconsistent and contain one (or more) spurious null displays. Note: the returned value will always be subject to TOC/TOU, of course, but this specific case has the returned value containing invalid displays with id=0 that were never supposed to be in the returned value in any possible state of the displays; this commit fixes this case.
This commit is contained in:
committed by
GitHub
parent
6940925635
commit
8002ddd167
@@ -460,10 +460,15 @@ impl CGDisplay {
|
||||
/// Provides a list of displays that are active (or drawable).
|
||||
#[inline]
|
||||
pub fn active_displays() -> Result<Vec<CGDirectDisplayID>, CGError> {
|
||||
let count = CGDisplay::active_display_count()?;
|
||||
let mut buf: Vec<CGDirectDisplayID> = vec![0; count as usize];
|
||||
let result = unsafe { CGGetActiveDisplayList(count, buf.as_mut_ptr(), ptr::null_mut()) };
|
||||
let expected_count = CGDisplay::active_display_count()?;
|
||||
let mut buf: Vec<CGDirectDisplayID> = vec![0; expected_count as usize];
|
||||
|
||||
let mut actual_count: u32 = 0;
|
||||
|
||||
let result =
|
||||
unsafe { CGGetActiveDisplayList(expected_count, buf.as_mut_ptr(), &mut actual_count) };
|
||||
if result == 0 {
|
||||
buf.truncate(actual_count as usize);
|
||||
Ok(buf)
|
||||
} else {
|
||||
Err(result)
|
||||
|
||||
Reference in New Issue
Block a user