Skip to content

Commit 7884b4b

Browse files
authored
Merge pull request #6604 from AvaloniaUI/fix/x11-freeze-segfault-on-close
[X11] Fixed potential freezes/segfaults on window close
2 parents 2dbc4be + acc6f6d commit 7884b4b

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class DeferredRenderer : RendererBase, IRenderer, IRenderLoopTask, IVisua
3535
private IRef<IDrawOperation> _currentDraw;
3636
private readonly IDeferredRendererLock _lock;
3737
private readonly object _sceneLock = new object();
38+
private readonly object _startStopLock = new object();
39+
private readonly object _renderLoopIsRenderingLock = new object();
3840
private readonly Action _updateSceneIfNeededDelegate;
3941

4042
/// <summary>
@@ -139,6 +141,8 @@ public void Dispose()
139141
}
140142

141143
Stop();
144+
// Wait for any in-progress rendering to complete
145+
lock(_renderLoopIsRenderingLock){}
142146
DisposeRenderTarget();
143147
}
144148

@@ -233,20 +237,26 @@ public void Resized(Size size)
233237
/// <inheritdoc/>
234238
public void Start()
235239
{
236-
if (!_running && _renderLoop != null)
240+
lock (_startStopLock)
237241
{
238-
_renderLoop.Add(this);
239-
_running = true;
242+
if (!_running && _renderLoop != null)
243+
{
244+
_renderLoop.Add(this);
245+
_running = true;
246+
}
240247
}
241248
}
242249

243250
/// <inheritdoc/>
244251
public void Stop()
245252
{
246-
if (_running && _renderLoop != null)
253+
lock (_startStopLock)
247254
{
248-
_renderLoop.Remove(this);
249-
_running = false;
255+
if (_running && _renderLoop != null)
256+
{
257+
_renderLoop.Remove(this);
258+
_running = false;
259+
}
250260
}
251261
}
252262

@@ -255,7 +265,16 @@ public void Stop()
255265

256266
void IRenderLoopTask.Update(TimeSpan time) => UpdateScene();
257267

258-
void IRenderLoopTask.Render() => Render(false);
268+
void IRenderLoopTask.Render()
269+
{
270+
lock (_renderLoopIsRenderingLock)
271+
{
272+
lock(_startStopLock)
273+
if(!_running)
274+
return;
275+
Render(false);
276+
}
277+
}
259278

260279
/// <inheritdoc/>
261280
Size IVisualBrushRenderer.GetRenderTargetSize(IVisualBrush brush)

src/Avalonia.X11/X11Window.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,13 +805,14 @@ void Cleanup()
805805

806806
if (_handle != IntPtr.Zero)
807807
{
808-
XDestroyWindow(_x11.Display, _handle);
809808
_platform.Windows.Remove(_handle);
810809
_platform.XI2?.OnWindowDestroyed(_handle);
810+
var handle = _handle;
811811
_handle = IntPtr.Zero;
812812
Closed?.Invoke();
813813
_mouse.Dispose();
814814
_touch.Dispose();
815+
XDestroyWindow(_x11.Display, handle);
815816
}
816817

817818
if (_useRenderWindow && _renderHandle != IntPtr.Zero)

0 commit comments

Comments
 (0)