Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/wayland/drm_syncobj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl Cacheable for DrmSyncobjCachedState {
#[derive(Debug)]
pub struct DrmSyncobjState {
global: GlobalId,
import_device: DrmDeviceFd,
import_device: Option<DrmDeviceFd>,
known_timelines: Vec<Weak<DrmTimelineInner>>,
}

Expand Down Expand Up @@ -155,11 +155,19 @@ impl DrmSyncobjState {

Self {
global,
import_device,
import_device: Some(import_device),
known_timelines: Vec::new(),
}
}

/// Closes the current `import_device`, allowing compositors to acquire a new fd.
///
/// Note: Any existing timeline objects will error out and hang clients,
/// until `update_device` is called with a new device fd.
Comment on lines +165 to +166
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if we use post_error, that won't just hang the client, it will cause the client to crash when its Wayland connection is broken by the protocol error, right?

pub fn close_device(&mut self) {
self.import_device.take();
}

/// Sets a new `import_device` to import the syncobj fds and wait on them.
///
/// Note: This will not update already existing timeline objects,
Expand All @@ -170,7 +178,7 @@ impl DrmSyncobjState {
warn!(?err, "Failed to update existing timeline");
}
}
self.import_device = import_device;
self.import_device = Some(import_device);
}

/// Destroys the state and returns the `GlobalId` for compositors to disable/destroy.
Expand Down Expand Up @@ -327,17 +335,23 @@ where
}
wp_linux_drm_syncobj_manager_v1::Request::ImportTimeline { id, fd } => {
if let Some(state) = state.drm_syncobj_state() {
match DrmTimeline::new(&state.import_device, fd) {
Ok(timeline) => {
match state.import_device.as_ref().map(|dev| DrmTimeline::new(dev, fd)) {
Some(Ok(timeline)) => {
state.known_timelines.push(Arc::downgrade(&timeline.0));
data_init.init::<_, _>(id, DrmSyncobjTimelineData { timeline });
}
Err(err) => {
Some(Err(err)) => {
resource.post_error(
wp_linux_drm_syncobj_manager_v1::Error::InvalidTimeline as u32,
format!("failed to import syncobj timeline: {err}"),
);
}
None => {
resource.post_error(
wp_linux_drm_syncobj_manager_v1::Error::InvalidTimeline as u32,
format!("failed to import syncobj timeline: No device"),
);
}
}
} else {
resource.post_error(
Expand Down
Loading