Skip to content

Instantly share code, notes, and snippets.

@zorael
Created January 2, 2024 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zorael/433c50f238b21b9bb68d076d8a495045 to your computer and use it in GitHub Desktop.
Save zorael/433c50f238b21b9bb68d076d8a495045 to your computer and use it in GitHub Desktop.
MutexedAA
import std;
import core.thread;
import core.time;
struct MutexedAA(AA : V[K], V, K)
{
import core.sync.mutex : Mutex;
shared Mutex mutex;
shared AA aa;
void setup() nothrow
{
mutex = new shared Mutex;
mutex.lock_nothrow();
if (K.init !in (cast()aa))
{
(cast()aa)[K.init] = V.init;
(cast()aa).remove(K.init);
}
mutex.unlock_nothrow();
}
auto opIndexAssign(V value, K key)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
(cast()aa)[key] = value;
mutex.unlock_nothrow();
return value;
}
auto opIndex(K key)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
auto value = (cast()aa)[key];
mutex.unlock_nothrow();
return value;
}
auto opBinaryRight(string op : "in")(K key)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
auto value = key in cast()aa;
mutex.unlock_nothrow();
return value;
}
auto remove(K key)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
auto value = (cast()aa).remove(key);
mutex.unlock_nothrow();
return value;
}
auto opEquals()(auto ref typeof(this) other)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
auto isEqual = (cast()aa == cast()(other.aa));
mutex.unlock_nothrow();
return isEqual;
}
auto opEquals()(auto ref AA other)
in (mutex, typeof(this).stringof ~ " has null Mutex")
{
mutex.lock_nothrow();
auto isEqual = (cast()aa == other);
mutex.unlock_nothrow();
return isEqual;
}
}
void main()
{
MutexedAA!(string[int]) aa;
aa.setup();
auto workerTid = spawn(&workerFn, aa);
foreach (int i; 0..10)
{
workerTid.send(i);
auto s = i in aa;
while (!s)
{
Thread.sleep(1.msecs);
s = i in aa;
}
assert(*s == i.to!string);
}
}
void workerFn(MutexedAA!(string[int]) aa)
{
bool halt;
while (!halt)
{
receive(
(int i)
{
aa[i] = i.to!string;
},
(OwnerTerminated _)
{
halt = true;
},
(Variant v)
{
halt = true;
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment