diff --git a/src/syndicate.nim b/src/syndicate.nim index 0760a22..d40453b 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -43,22 +43,22 @@ export Actor, Assertion, Facet, Handle, Ref, Symbol, Turn, TurnAction, type Observe* = dataspace.Observe[Ref] - PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure.} - RetractProc = proc (turn: var Turn; h: Handle) {.closure.} - MessageProc = proc (turn: var Turn; v: Assertion) {.closure.} + PublishProc = proc (turn: var Turn; v: Assertion; h: Handle) {.closure, gcsafe.} + RetractProc = proc (turn: var Turn; h: Handle) {.closure, gcsafe.} + MessageProc = proc (turn: var Turn; v: Assertion) {.closure, gcsafe.} ClosureEntity = ref object of Entity publishImpl: PublishProc retractImpl: RetractProc messageImpl: MessageProc -method publish(e: ClosureEntity; turn: var Turn; v: Assertion; h: Handle) = - if not e.publishImpl.isNil: e.publishImpl(turn, v, h) +method publish(e: ClosureEntity; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} = + if not e.publishImpl.isNil: e.publishImpl(turn, a.value, h) -method retract(e: ClosureEntity; turn: var Turn; h: Handle) = +method retract(e: ClosureEntity; turn: var Turn; h: Handle) {.gcsafe.} = if not e.retractImpl.isNil: e.retractImpl(turn, h) -method message(e: ClosureEntity; turn: var Turn; v: Assertion) = - if not e.messageImpl.isNil: e.messageImpl(turn, v) +method message(e: ClosureEntity; turn: var Turn; a: AssertionRef) {.gcsafe.} = + if not e.messageImpl.isNil: e.messageImpl(turn, a.value) proc argumentCount(handler: NimNode): int = handler.expectKind {nnkDo, nnkStmtList} diff --git a/src/syndicate/actors.nim b/src/syndicate/actors.nim index 68e0747..f0cd8d3 100644 --- a/src/syndicate/actors.nim +++ b/src/syndicate/actors.nim @@ -7,8 +7,6 @@ import ../syndicate/protocols/[protocol, sturdy] export Handle -# proc `==`*(x, y: Handle): bool {.borrow.} - template generateIdType(T: untyped) = type T* = distinct Natural proc `==`*(x, y: T): bool {.borrow.} @@ -20,11 +18,6 @@ generateIdType(EndpointId) generateIdType(FieldId) generateIdType(TurnId) -#[ -proc genId(T: type): T = - getMonotime().ticks.T -]# - type Attenuation = sturdy.Attenuation[Ref] Oid = sturdy.Oid @@ -78,17 +71,22 @@ type inertCheckPreventers: int isAlive: bool +type AssertionRef* = ref object + value*: Preserve[Ref] + # if the Enity methods take a Preserve[Ref] object then the generated + # C code has "redefinition of struct" problems when orc is enabled + +method publish*(e: Entity; turn: var Turn; v: AssertionRef; h: Handle) {.base, gcsafe.} = discard +method retract*(e: Entity; turn: var Turn; h: Handle) {.base, gcsafe.} = discard +method message*(e: Entity; turn: var Turn; v: AssertionRef) {.base, gcsafe.} = discard +method sync*(e: Entity; turn: var Turn; peer: Ref) {.base, gcsafe.} = discard + using actor: Actor facet: Facet turn: var Turn action: TurnAction -method publish*(e: Entity; turn: var Turn; v: Assertion; h: Handle) {.base.} = discard -method retract*(e: Entity; turn: var Turn; h: Handle) {.base.} = discard -method message*(e: Entity; turn: var Turn; v: Assertion) {.base.} = discard -method sync*(e: Entity; turn: var Turn; peer: Ref) {.base.} = discard - proc labels(f: Facet): string = proc catLabels(f: Facet; labels: var string) = labels.add ':' @@ -243,14 +241,14 @@ proc runRewrites*(a: Attenuation; v: Assertion): Assertion = if result.isFalse: break proc publish(turn: var Turn; r: Ref; v: Assertion; h: Handle) = - let a = runRewrites(r.attenuation, v) + var a = runRewrites(r.attenuation, v) if not a.isFalse: let e = OutboundAssertion( handle: h, peer: r, established: false) turn.facet.outbound[h] = e enqueue(turn, r.relay) do (turn: var Turn): e.established = true - publish(r.target, turn, a, e.handle) + publish(r.target, turn, AssertionRef(value: a), e.handle) proc publish*(turn: var Turn; r: Ref; a: Assertion): Handle = result = turn.facet.nextHandle() @@ -271,10 +269,10 @@ proc retract*(turn: var Turn; h: Handle) = turn.retract(e) proc message*(turn: var Turn; r: Ref; v: Assertion) = - let a = runRewrites(r.attenuation, v) + var a = runRewrites(r.attenuation, v) if not a.isFalse: enqueue(turn, r.relay) do (turn: var Turn): - r.target.message(turn, a) + r.target.message(turn, AssertionRef(value: a)) proc message*[T](turn: var Turn; r: Ref; v: T) = message(turn, r, toPreserve(v, Ref)) diff --git a/src/syndicate/dataspaces.nim b/src/syndicate/dataspaces.nim index c263f11..47ed869 100644 --- a/src/syndicate/dataspaces.nim +++ b/src/syndicate/dataspaces.nim @@ -16,14 +16,14 @@ type index: Index handleMap: Table[Handle, Assertion] -method publish(ds: Dataspace; turn: var Turn; v: Assertion; h: Handle) = - if add(ds.index, turn, v): +method publish(ds: Dataspace; turn: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} = + if add(ds.index, turn, a.value): var obs: Observe - if obs.fromPreserve v: + if obs.fromPreserve a.value: ds.index.add(turn, obs.pattern, obs.observer) - ds.handleMap[h] = v + ds.handleMap[h] = a.value -method retract(ds: Dataspace; turn: var Turn; h: Handle) = +method retract(ds: Dataspace; turn: var Turn; h: Handle) {.gcsafe.} = try: let v = ds.handleMap[h] if remove(ds.index, turn, v): @@ -33,8 +33,8 @@ method retract(ds: Dataspace; turn: var Turn; h: Handle) = ds.index.remove(turn, obs.pattern, obs.observer) except KeyError: discard -method message(ds: Dataspace; turn: var Turn; v: Assertion) = - ds.index.deliverMessage(turn, v) +method message(ds: Dataspace; turn: var Turn; a: AssertionRef) {.gcsafe.} = + ds.index.deliverMessage(turn, a.value) proc newDataspace*(turn: var Turn): Ref = newRef(turn, Dataspace(index: initIndex())) diff --git a/src/syndicate/durings.nim b/src/syndicate/durings.nim index 26c4bd4..1d51bcd 100644 --- a/src/syndicate/durings.nim +++ b/src/syndicate/durings.nim @@ -23,8 +23,8 @@ type cb: DuringProc assertionMap: Table[Handle, DuringAction] -method publish(de: DuringEntity; turn: var Turn; a: Assertion; h: Handle) = - let action = de.cb(turn, a, h) +method publish(de: DuringEntity; turn: var Turn; a: AssertionRef; h: Handle) = + let action = de.cb(turn, a.value, h) # assert(not action.isNil "should have put in a no-op action") let g = de.assertionMap.getOrDefault h case g.kind diff --git a/src/syndicate/relays.nim b/src/syndicate/relays.nim index af6afee..6be59b9 100644 --- a/src/syndicate/relays.nim +++ b/src/syndicate/relays.nim @@ -53,18 +53,18 @@ type proc releaseRefOut(r: Relay; e: WireSymbol) = r.exported.drop e -method publish(spe: SyncPeerEntity; t: var Turn; v: Assertion; h: Handle) = - spe.handleMap[h] = publish(t, spe.peer, v) +method publish(spe: SyncPeerEntity; t: var Turn; a: AssertionRef; h: Handle) = + spe.handleMap[h] = publish(t, spe.peer, a.value) method retract(se: SyncPeerEntity; t: var Turn; h: Handle) = var other: Handle if se.handleMap.pop(h, other): retract(t, other) -method message(se: SyncPeerEntity; t: var Turn; v: Assertion) = +method message(se: SyncPeerEntity; t: var Turn; a: AssertionRef) = if not se.e.isNil: se.relay.releaseRefOut(se.e) - message(t, se.peer, v) + message(t, se.peer, a.value) method sync(se: SyncPeerEntity; t: var Turn; peer: Ref) = sync(t, se.peer, peer) @@ -87,7 +87,7 @@ proc rewriteRefOut(relay: Relay; `ref`: Ref; transient: bool; exported: var seq[ mine: WireRefMine(oid: ws.oid)) proc rewriteOut(relay: Relay; v: Assertion; transient: bool): - tuple[rewritten: Value, exported: seq[WireSymbol]] = + tuple[rewritten: Value, exported: seq[WireSymbol]] {.gcsafe.} = var exported: seq[WireSymbol] result.rewritten = contract(v) do (r: Ref) -> Value: rewriteRefOut(relay, r, transient, exported).toPreserve @@ -124,24 +124,24 @@ proc send(r: Relay; rOid: protocol.Oid; m: Event) = proc send(re: RelayEntity; ev: Event) = send(re.relay, protocol.Oid re.oid, ev) -method publish(re: RelayEntity; t: var Turn; v: Assertion; h: Handle) = +method publish(re: RelayEntity; t: var Turn; a: AssertionRef; h: Handle) {.gcsafe.} = re.send Event( orKind: EventKind.Assert, `assert`: protocol.Assert( - assertion: re.relay.register(v, h), + assertion: re.relay.register(a.value, h), handle: h)) -method retract(re: RelayEntity; t: var Turn; h: Handle) = +method retract(re: RelayEntity; t: var Turn; h: Handle) {.gcsafe.} = re.relay.deregister h re.send Event( orKind: EventKind.Retract, retract: Retract(handle: h)) -method message(re: RelayEntity; turn: var Turn; msg: Assertion) = +method message(re: RelayEntity; turn: var Turn; msg: AssertionRef) {.gcsafe.} = re.send Event(orKind: EventKind.Message, - message: Message(body: register(re.relay, msg))) + message: Message(body: register(re.relay, msg.value))) -method sync(re: RelayEntity; turn: var Turn; peer: Ref) = +method sync(re: RelayEntity; turn: var Turn; peer: Ref) {.gcsafe.} = var peerEntity = newSyncPeerEntity(re.relay, peer) exported: seq[WireSymbol] @@ -181,7 +181,7 @@ proc rewriteRefIn(relay; facet; n: WireRef, imported: var seq[WireSymbol]): Ref else: raiseAssert "attenuation not implemented" proc rewriteIn(relay; facet; v: Value): - tuple[rewritten: Assertion; imported: seq[WireSymbol]] = + tuple[rewritten: Assertion; imported: seq[WireSymbol]] {.gcsafe.} = var imported: seq[WireSymbol] result.rewritten = expand(v) do (pr: Value) -> Assertion: var wr: WireRef @@ -192,7 +192,7 @@ proc rewriteIn(relay; facet; v: Value): proc close(r: Relay) = discard -proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) = +proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) {.gcsafe.} = case event.orKind of EventKind.Assert: let (a, imported) = rewriteIn(relay, turn.facet, event.assert.assertion) @@ -220,7 +220,7 @@ proc dispatch*(relay: Relay; turn: var Turn; `ref`: Ref; event: Event) = for e in imported: relay.imported.del e ]# -proc dispatch*(relay: Relay; v: Value) = +proc dispatch*(relay: Relay; v: Value) {.gcsafe.} = trace "S: ", v run(relay.facet) do (t: var Turn): var pkt: Packet diff --git a/src/syndicate/skeletons.nim b/src/syndicate/skeletons.nim index 9739d83..e6170b3 100644 --- a/src/syndicate/skeletons.nim +++ b/src/syndicate/skeletons.nim @@ -64,9 +64,9 @@ func isEmpty(leaf: Leaf): bool = leaf.cachedAssertions.len == 0 and leaf.observerGroups.len == 0 type - ContinuationProc = proc (c: Continuation; v: Value) - LeafProc = proc (l: Leaf; v: Value) - ObserverProc = proc (turn: var Turn; group: ObserverGroup; vs: seq[Value]) + ContinuationProc = proc (c: Continuation; v: Value) {.gcsafe.} + LeafProc = proc (l: Leaf; v: Value) {.gcsafe.} + ObserverProc = proc (turn: var Turn; group: ObserverGroup; vs: seq[Value]) {.gcsafe.} type TermStack = SinglyLinkedList[Value]