Skip to content

Commit 8002ddd

Browse files
authored
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.
1 parent 6940925 commit 8002ddd

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

core-graphics/src/display.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,15 @@ impl CGDisplay {
460460
/// Provides a list of displays that are active (or drawable).
461461
#[inline]
462462
pub fn active_displays() -> Result<Vec<CGDirectDisplayID>, CGError> {
463-
let count = CGDisplay::active_display_count()?;
464-
let mut buf: Vec<CGDirectDisplayID> = vec![0; count as usize];
465-
let result = unsafe { CGGetActiveDisplayList(count, buf.as_mut_ptr(), ptr::null_mut()) };
463+
let expected_count = CGDisplay::active_display_count()?;
464+
let mut buf: Vec<CGDirectDisplayID> = vec![0; expected_count as usize];
465+
466+
let mut actual_count: u32 = 0;
467+
468+
let result =
469+
unsafe { CGGetActiveDisplayList(expected_count, buf.as_mut_ptr(), &mut actual_count) };
466470
if result == 0 {
471+
buf.truncate(actual_count as usize);
467472
Ok(buf)
468473
} else {
469474
Err(result)

0 commit comments

Comments
 (0)