Skip to content

Commit

Permalink
fix: Use object pool to produce colorizer frames to avoid race condit…
Browse files Browse the repository at this point in the history
…ions. Fixes #435.
  • Loading branch information
freezy committed Sep 10, 2023
1 parent 72d5d32 commit a011438
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
5 changes: 3 additions & 2 deletions LibDmd/Converter/AbstractConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public virtual void Convert(DmdFrame frame)
}
#endif
_lastDmdFrame = PadSmallFrames && frame.Dimensions.IsSmallerThan(Dimensions.Standard)
? frame.Update(Dimensions.Standard, frame.CenterFrame(Dimensions.Standard, frame.Data, frame.BytesPerPixel), frame.BitLength)
: frame;
? DmdFrame.GetFromPool().Update(Dimensions.Standard, frame.CenterFrame(Dimensions.Standard, frame.Data, frame.BytesPerPixel), frame.BitLength)
: DmdFrame.GetFromPool().Update(frame);
}

/// <summary>
Expand Down Expand Up @@ -140,6 +140,7 @@ private void Tick(long _)
{
if (_lastDmdFrame != null) {
ConvertClocked(_lastDmdFrame);
_lastDmdFrame.ReturnToPool();
}

if (_lastAlphanumFrame != null) {
Expand Down
24 changes: 24 additions & 0 deletions LibDmd/Frame/DmdFrame.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
Expand Down Expand Up @@ -44,6 +45,8 @@ public class DmdFrame : BaseFrame, ICloneable, IEqualityComparer<DmdFrame>
public static bool operator == (DmdFrame x, DmdFrame y) => Equals(x, y);
public static bool operator != (DmdFrame x, DmdFrame y) => !Equals(x, y);

private static ObjectPool Pool = new ObjectPool();

public FrameFormat Format {
get {
switch (BitLength) {
Expand Down Expand Up @@ -554,6 +557,27 @@ public override string ToString()

#endregion

#region Pool

private class ObjectPool
{
private readonly ConcurrentBag<DmdFrame> _objects;

public ObjectPool()
{
_objects = new ConcurrentBag<DmdFrame>();
}

public DmdFrame Get() => _objects.TryTake(out DmdFrame item) ? item : new DmdFrame();

public void Return(DmdFrame item) => _objects.Add(item);
}

public static DmdFrame GetFromPool() => Pool.Get();
public void ReturnToPool() => Pool.Return(this);

#endregion

#region Debug

public void Dump(string path, string prefix = null)
Expand Down

0 comments on commit a011438

Please sign in to comment.