This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch wl/real-browser
in repository enlightenment.

View the commit online.

commit 1a081cccd8b0bf7695896cf2ba3e984f34fcfa45
Author: Cedric BAIL <[email protected]>
AuthorDate: Sun Aug 16 22:47:36 2026 -0600

    e_pixmap - do not hand back a buffer the renderer may still be reading
    
    Dragging a window's corner to resize it killed the compositor, every time:
    
        #0 _evas_common_scale_rgba_sample_scale_nomask
        #1 evas_common_scale_rgba_sample_draw
        #2 _draw_thread_image_draw
        #3 evas_thread_worker_func
    
    SEGV_MAPERR in evas's async render thread, reading image data that is no
    longer mapped.
    
    e_pixmap already knows about this. _e_pixmap_wayland_buffer_release holds a
    release back while e_comp->rendering, precisely so a client is not told it may
    reuse or destroy a buffer the compositor has not finished with.
    e_pixmap_resource_set did not go through it - it called
    _e_pixmap_wl_resource_release directly, with the busy_list bookkeeping copied
    inline - so the one path that always fires on a client committing a *new*
    buffer was the one path with no deferral.
    
    That is the worst place to miss it. Committing a new buffer is exactly when the
    old one gets handed back, and during a resize new buffers arrive faster than
    frames go out. The client did what it is entitled to do: it got the release, it
    destroyed the buffer, libwayland dropped the shm pool's mapping, and the worker
    was still reading from it. Every toolkit destroys released buffers - the test
    client here does, and so does every browser. It just takes a resize to make the
    overlap likely enough to hit every time.
    
    So call the wrapper. The busy_list handling it does inline is the same handling
    the wrapper already has, so nothing else changes.
    
    Found by test_client_move.c, which drives an interactive corner drag through
    E's own resize grab; it crashed the compositor on every run before this and
    passes five for five after. wl-globals, all eleven protocol tests and
    e_wlcs_driver pass.
    
    One thing deliberately not changed: e_comp->rendering is cleared from
    RENDER_FLUSH_POST, which is when drawing is handed to evas rather than when the
    worker has finished with it, so in principle the deferral window closes early.
    Moving it to RENDER_POST also fixes this crash - but so does the one-line
    change above on its own, five runs out of five, and a stuck rendering flag
    would starve every client of buffer releases. Not worth trading a crash I can
    reproduce for a hang I cannot.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 src/bin/e_pixmap.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/bin/e_pixmap.c b/src/bin/e_pixmap.c
index 0c14e569c..16e1461fb 100644
--- a/src/bin/e_pixmap.c
+++ b/src/bin/e_pixmap.c
@@ -763,18 +763,23 @@ e_pixmap_resource_set(E_Pixmap *cp, void *resource)
 #ifdef HAVE_WAYLAND
    if (cp->buffer == resource) return;
 
-   if (cp->buffer)
-     {
-        if (resource)
-          {
-        if (cp->buffer->busy == 1)
-          {
-             // about to go to busy 0, so remove from list
-             cp->busy_list = eina_list_remove(cp->busy_list, cp->buffer);
-          }
-        _e_pixmap_wl_resource_release(cp->buffer);
-          }
-     }
+   /* Through _e_pixmap_wayland_buffer_release, not straight to
+    * _e_pixmap_wl_resource_release. The difference is the only thing standing
+    * between a client and a compositor crash: the wrapper holds a release back
+    * while a render is in flight, and this is exactly when that matters - the
+    * client has just committed a new buffer, so the old one is about to be
+    * handed back while evas may still be reading it from a worker thread.
+    *
+    * Releasing it immediately told the client it could destroy the buffer, and
+    * destroying it dropped the shm mapping the worker was reading, inside
+    * evas_common_scale_rgba_sample_draw. It takes a resize to make it likely
+    * enough to see, because that is when new buffers arrive faster than frames
+    * go out - but every toolkit destroys released buffers, so nothing about it
+    * is exotic.
+    *
+    * The busy_list bookkeeping this used to do inline lives in the wrapper. */
+   if (cp->buffer && resource)
+     _e_pixmap_wayland_buffer_release(cp, cp->buffer);
 
    if (cp->buffer_destroy_listener.notify)
      {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to