diff --git a/src/cpu_worker.rs b/src/cpu_worker.rs index 3383de6e..578a8d46 100644 --- a/src/cpu_worker.rs +++ b/src/cpu_worker.rs @@ -200,6 +200,15 @@ impl Drop for PendingJob { } impl CpuWorkerData { + fn clear(&self) { + self.jobs_to_enqueue.clear(); + self.new_jobs.lock().clear(); + self.completed_jobs_remote.lock().queue.clear(); + self.completed_jobs_local.borrow_mut().clear(); + self.pending_jobs.clear(); + self.pending_job_data_cache.take(); + } + async fn wait_for_completions(self: Rc) { let mut buf = TypedBuf::::new(); loop { @@ -302,6 +311,10 @@ impl CpuWorker { }) } + pub fn clear(&self) { + self.data.clear(); + } + pub fn submit(&self, job: Box) -> PendingJob { let mut job = NonNull::from(Box::leak(job)); let id = self.data.next.next(); diff --git a/src/criteria/clm.rs b/src/criteria/clm.rs index 57a929cf..022be1a0 100644 --- a/src/criteria/clm.rs +++ b/src/criteria/clm.rs @@ -63,6 +63,18 @@ pub struct RootMatchers { exe: ClmRootMatcherMap, } +impl RootMatchers { + fn clear(&self) { + self.sandbox_app_id.clear(); + self.sandbox_engine.clear(); + self.sandbox_instance_id.clear(); + self.uid.clear(); + self.pid.clear(); + self.comm.clear(); + self.exe.clear(); + } +} + pub async fn handle_cl_changes(state: Rc) { let mgr = &state.cl_matcher_manager; loop { @@ -112,6 +124,10 @@ impl ClMatcherManager { pub fn clear(&self) { self.changes.clear(); self.leaf_events.clear(); + self.constant.values().for_each(|c| c.clear()); + self.sandboxed.values().for_each(|c| c.clear()); + self.is_xwayland.values().for_each(|c| c.clear()); + self.matchers.clear(); } pub fn rematch_all(&self, state: &Rc) { diff --git a/src/criteria/crit_graph/crit_root.rs b/src/criteria/crit_graph/crit_root.rs index c8ca8abd..3c2c6f4c 100644 --- a/src/criteria/crit_graph/crit_root.rs +++ b/src/criteria/crit_graph/crit_root.rs @@ -129,6 +129,10 @@ where slf } + pub fn clear(&self) { + self.downstream.clear(); + } + pub fn handle(&self, target: &Target) { let new = self.criterion.matches(target) ^ self.not; let node = match new { diff --git a/src/criteria/crit_graph/crit_upstream.rs b/src/criteria/crit_graph/crit_upstream.rs index 7e21c78e..df799075 100644 --- a/src/criteria/crit_graph/crit_upstream.rs +++ b/src/criteria/crit_graph/crit_upstream.rs @@ -125,6 +125,10 @@ where } } + pub fn clear(&self) { + self.nodes.clear() + } + pub fn update_matched( &self, target: &Target, diff --git a/src/criteria/crit_per_target_data.rs b/src/criteria/crit_per_target_data.rs index 6ce7aca1..d675513c 100644 --- a/src/criteria/crit_per_target_data.rs +++ b/src/criteria/crit_per_target_data.rs @@ -56,6 +56,10 @@ where } } + pub fn clear(&self) { + self.data.borrow_mut().clear(); + } + pub fn get_or_create(&self, target: &Target, default: impl FnOnce() -> T) -> RefMut { RefMut::map(self.data.borrow_mut(), |d| { &mut d diff --git a/src/criteria/tlm.rs b/src/criteria/tlm.rs index cdaeac99..29cca67b 100644 --- a/src/criteria/tlm.rs +++ b/src/criteria/tlm.rs @@ -95,6 +95,22 @@ pub struct RootMatchers { content_ty: TlmRootMatcherMap, } +impl RootMatchers { + fn clear(&self) { + self.kinds.clear(); + self.clients.clear(); + self.title.clear(); + self.tag.clear(); + self.app_id.clear(); + self.seat_foci.clear(); + self.class.clear(); + self.instance.clear(); + self.role.clear(); + self.workspace.clear(); + self.content_ty.clear(); + } +} + pub async fn handle_tl_changes(state: Rc) { let mgr = &state.tl_matcher_manager; loop { @@ -159,6 +175,13 @@ impl TlMatcherManager { self.changes.clear(); self.leaf_events.clear(); self.handle_just_mapped.clear(); + self.constant.values().for_each(|c| c.clear()); + self.floating.values().for_each(|c| c.clear()); + self.visible.values().for_each(|c| c.clear()); + self.urgent.values().for_each(|c| c.clear()); + self.fullscreen.values().for_each(|c| c.clear()); + self.just_mapped.values().for_each(|c| c.clear()); + self.matchers.clear(); } pub fn rematch_all(&self, state: &Rc) { diff --git a/src/leaks.rs b/src/leaks.rs index 211d3933..da3ad06f 100644 --- a/src/leaks.rs +++ b/src/leaks.rs @@ -272,7 +272,8 @@ mod leaks { unsafe impl GlobalAlloc for TracingAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { unsafe { - let res = c::calloc(layout.size(), 1) as *mut u8; + let res = c::aligned_alloc(layout.align(), layout.size()) as *mut u8; + c::memset(res.cast(), 0, layout.size()); if IN_ALLOCATOR.get() == 0 { IN_ALLOCATOR.set(1); ALLOCATIONS.get().deref_mut().insert( diff --git a/src/state.rs b/src/state.rs index 1fb6235c..1ea2ac4a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1006,6 +1006,7 @@ impl State { self.run_toplevel.clear(); self.xwayland.handler.borrow_mut().take(); self.xwayland.queue.clear(); + self.xwayland.windows.clear(); self.idle.inhibitors.clear(); self.idle.change.clear(); for drm_dev in self.drm_devs.lock().drain_values() { @@ -1068,6 +1069,11 @@ impl State { self.position_hint_requests.clear(); self.head_managers.clear(); self.head_managers_async.clear(); + self.const_40hz_latch.clear(); + self.cursor_user_groups.clear(); + self.cursor_user_group_hardware_cursor.take(); + self.cpu_worker.clear(); + self.wait_for_sync_obj.clear(); } pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) { diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index aed36666..f7960960 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -404,6 +404,7 @@ impl ConnectorHandler { } self.state .remove_output_scale(on.global.persistent.scale.get()); + on.clear(); let _ = self.state.remove_global(&global); let _ = self.state.remove_global(&tray); self.state.tree_changed(); diff --git a/src/tree/output.rs b/src/tree/output.rs index 2da49494..928531f2 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -439,13 +439,16 @@ impl OutputNode { for workspace in workspaces { workspace.clear(); } - self.render_data.borrow_mut().titles.clear(); self.lock_surface.take(); self.jay_outputs.clear(); self.screencasts.clear(); self.screencopies.clear(); self.ext_copy_sessions.clear(); self.ext_workspace_groups.clear(); + self.latch_event.clear(); + self.vblank_event.clear(); + self.presentation_event.clear(); + self.render_data.borrow_mut().clear(); } pub fn on_spaces_changed(self: &Rc) { @@ -1418,6 +1421,13 @@ pub struct OutputRenderData { pub status: Option, } +impl OutputRenderData { + fn clear(&mut self) { + self.titles.clear(); + self.status.take(); + } +} + impl Debug for OutputNode { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("OutputNode").finish_non_exhaustive() diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index f081f751..f6ec75b5 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -77,6 +77,7 @@ impl WorkspaceNode { self.jay_workspaces.clear(); self.ext_workspaces.clear(); self.opt.set(None); + self.title_texture.take(); } pub fn update_has_captures(&self) { diff --git a/src/utils/event_listener.rs b/src/utils/event_listener.rs index 784ed72f..2bed98b1 100644 --- a/src/utils/event_listener.rs +++ b/src/utils/event_listener.rs @@ -25,6 +25,10 @@ impl Default for EventSource { } impl EventSource { + pub fn clear(&self) { + self.on_attach.take(); + } + pub fn iter(&self) -> EventSourceIter { EventSourceIter { iter: self.listeners.iter(), diff --git a/src/video/drm/wait_for_sync_obj.rs b/src/video/drm/wait_for_sync_obj.rs index 58be19e5..3ce0a57c 100644 --- a/src/video/drm/wait_for_sync_obj.rs +++ b/src/video/drm/wait_for_sync_obj.rs @@ -87,6 +87,12 @@ impl WaitForSyncObj { } } + pub fn clear(&self) { + self.inner.ctx.take(); + self.inner.busy.clear(); + self.inner.idle.take(); + } + pub fn set_ctx(&self, ctx: Option>) { self.inner.ctx.set(ctx); let busy_waiters: Vec<_> = self.inner.busy.lock().drain_values().collect(); @@ -163,13 +169,6 @@ impl WaitForSyncObj { } } -impl Drop for WaitForSyncObj { - fn drop(&mut self) { - self.inner.busy.clear(); - self.inner.idle.take(); - } -} - impl WaiterInner { async fn run(self: Rc) { let mut buf = Buf::new(8); diff --git a/src/xwayland.rs b/src/xwayland.rs index 6d6fb1e1..b5a65f48 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -203,6 +203,7 @@ async fn run( state.ring.readable(&pidfd).await?; } state.xwayland.queue.clear(); + state.xwayland.windows.clear(); stderr_read.await; Ok(()) }