{"record":{"id":"f9b4944e4e320ecf","repo":"linebender/druid","slug":"destroying-a-buffer-while-it-is-in-use","errorCode":null,"errorMessage":"Destroying a buffer while it is in use","messagePattern":"Destroying a buffer while it is in use","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"druid-shell/src/backend/wayland/surfaces/buffers.rs","lineNumber":293,"sourceCode":"                }\n                _ => tracing::warn!(\"unhandled wayland buffer event: {:?} {:?}\", b, event),\n            }\n        }));\n\n        Buffer { inner, in_use }\n    }\n\n    pub fn attach(&self, wl_surface: &wl::Main<WlSurface>) {\n        if self.in_use.get() {\n            panic!(\"attaching an already in-use surface\");\n        }\n        self.in_use.set(true);\n        wl_surface.attach(Some(&self.inner), 0, 0);\n    }\n\n    pub fn destroy(&self) {\n        if self.in_use.get() {\n            panic!(\"Destroying a buffer while it is in use\");\n        }\n        self.inner.destroy();\n    }\n}\n\npub struct BufferData<const N: usize> {\n    buffers: WeakRc<Buffers<N>>,\n    mmap: Mmap,\n}\n\nimpl<const N: usize> Deref for BufferData<N> {\n    type Target = [u8];\n\n    fn deref(&self) -> &[u8] {\n        self.mmap.deref()\n    }\n}\n","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid-shell/src/backend/wayland/surfaces/buffers.rs#L275-L311","documentation":"Guard panic in Buffer::destroy: the buffer is still marked in-use (attached to a surface and not yet released by the compositor), so destroying it now would violate the wl_buffer protocol and cause protocol errors. It fires when caller code tears down a surface's buffer pool before the compositor has released the buffer.","triggerScenarios":"Thrown at druid-shell/src/backend/wayland/surfaces/buffers.rs:293 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Wait for the compositor's wl_buffer.release event and clear the in_use flag before calling destroy","Defer destruction of the buffer to the release callback or drop path","If the surface is being torn down, let the compositor clean up by dropping the wl_buffer proxy without an explicit destroy-while-attached"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}