1 2 3 module rwslist; 4 5 import llist.slist; 6 7 import core.sync.rwmutex; 8 9 10 ///A bundle of values for the SList payload. 11 private struct Bundle(T) { 12 T payload; 13 ReadWriteMutex mutex; 14 } 15 private Bundle!T newBundle(T)() { 16 auto b = Bundle!T(); 17 b.initialize; 18 return b; 19 } 20 private Bundle!T newBundle(T)(T payload) { 21 Bundle!T b = Bundle!T(payload); 22 b.initialize; 23 return b; 24 } 25 private void initialize(T)(ref Bundle!T bundle) { 26 bundle.mutex = new ReadWriteMutex; 27 } 28 29 class RwSList(T) { 30 private alias NodeT = Node!(Bundle!T)*; 31 NodeT slist; 32 NodeT last; 33 this() { 34 slist = new Node!(Bundle!T); 35 slist.payload = newBundle!T(); 36 last = slist; 37 } 38 void iterate(bool delegate(const(T)) callback) { 39 NodeT node=slist; 40 while (true) { 41 //---lock 42 node.payload.mutex.reader.lock; 43 NodeT lockedNode = node; 44 scope(exit) lockedNode.payload.mutex.reader.unlock; 45 //---empty 46 if (node.empty) break; 47 //---callback 48 if (!callback(node.payload.payload)) break; 49 //---move to next 50 node = node.next; 51 //---unlock 52 // Done in `scope(exit)` 53 } 54 } 55 void writeIterate(bool delegate(T, void delegate() remove) callback) { 56 NodeT lastNode=null; 57 NodeT node=slist; 58 while (true) { 59 //---lock 60 node.payload.mutex.writer.lock; 61 //---empty 62 if (node.empty) { 63 lastNode.payload.mutex.writer.unlock; 64 node.payload.mutex.writer.unlock; 65 break; 66 } 67 //---callback 68 if (!callback(node.payload.payload, (){lastNode.removeNext;})) break; 69 //---unlock old node (does not need to happen after "move to next" because `last` does not get used) 70 if (lastNode!=null) { 71 lastNode.payload.mutex.writer.unlock; 72 } 73 //---move to next 74 lastNode = node; 75 node = node.next; 76 } 77 } 78 void put(T value) { 79 last.payload.mutex.writer.lock; 80 NodeT lockedNode = last; 81 scope(exit) lockedNode.payload.mutex.writer.unlock; 82 83 last.append(newBundle(value)); 84 last = last.next; 85 last.payload = newBundle!T(); 86 } 87 } 88 89 90 91 unittest { 92 import std.stdio; 93 94 class A { 95 int a = 0; 96 uint[5] b = [5652,144,1,684,888]; 97 this(int a) { 98 this.a = a; 99 } 100 } 101 102 RwSList!A list = new RwSList!A; 103 104 list.put(new A(1)); 105 list.put(new A(2)); 106 list.put(new A(3)); 107 list.put(new A(4)); 108 list.put(new A(5)); 109 list.put(new A(6)); 110 list.put(new A(7)); 111 112 list.iterate((const A a){a.a.writeln; a.b.writeln; return true;}); 113 list.writeIterate((A a, void delegate() remove){a.a++; a.b.writeln; return true;}); 114 list.iterate((const A a){a.a.writeln; a.b.writeln; return true;}); 115 } 116 117 118 119