1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
discard """
targets: "c js"
"""
# bug #21306
type
FutureState {.pure.} = enum
Pending, Finished, Cancelled, Failed
FutureBase = ref object of RootObj
state: FutureState
error: ref CatchableError
id: uint
Future[T] = ref object of FutureBase
closure: iterator(f: Future[T]): FutureBase {.raises: [Defect, CatchableError, Exception], gcsafe.}
value: T
template setupFutureBase() =
new(result)
result.state = FutureState.Pending
proc newFutureImpl[T](): Future[T] =
setupFutureBase()
template newFuture[T](fromProc: static[string] = ""): Future[T] =
newFutureImpl[T]()
proc internalRead[T](fut: Future[T]): T =
when T isnot void:
return fut.value
template await[T](f: Future[T]): untyped =
when declared(chronosInternalRetFuture):
when not declaredInScope(chronosInternalTmpFuture):
var chronosInternalTmpFuture {.inject.}: FutureBase = f
else:
chronosInternalTmpFuture = f
yield chronosInternalTmpFuture
when T isnot void:
cast[type(f)](chronosInternalTmpFuture).internalRead()
type
VerifierError {.pure.} = enum
Invalid
MissingParent
UnviableFork
Duplicate
ProcessingCallback = proc() {.gcsafe, raises: [Defect].}
BlockVerifier =
proc(signedBlock: int):
Future[VerifierError] {.gcsafe, raises: [Defect].}
SyncQueueKind {.pure.} = enum
Forward, Backward
SyncRequest[T] = object
kind: SyncQueueKind
index: uint64
slot: uint64
count: uint64
item: T
SyncResult[T] = object
request: SyncRequest[T]
data: seq[ref int]
SyncQueue[T] = ref object
kind: SyncQueueKind
readyQueue: seq[SyncResult[T]]
blockVerifier: BlockVerifier
iterator blocks[T](sq: SyncQueue[T],
sr: SyncResult[T]): ref int =
case sq.kind
of SyncQueueKind.Forward:
for i in countup(0, len(sr.data) - 1):
yield sr.data[i]
of SyncQueueKind.Backward:
for i in countdown(len(sr.data) - 1, 0):
yield sr.data[i]
proc push[T](sq: SyncQueue[T]; sr: SyncRequest[T]; data: seq[ref int];
processingCb: ProcessingCallback = nil): Future[void] {.
stackTrace: off, gcsafe.} =
iterator push_436208182(chronosInternalRetFuture: Future[void]): FutureBase {.
closure, gcsafe, raises: [Defect, CatchableError, Exception].} =
block:
template result(): auto {.used.} =
{.fatal: "You should not reference the `result` variable inside" &
" a void async proc".}
let item = default(SyncResult[T])
for blk in sq.blocks(item):
let res = await sq.blockVerifier(blk[])
var resultFuture = newFuture[void]("push")
resultFuture.closure = push_436208182
return resultFuture
type
SomeTPeer = ref object
score: int
proc getSlice(): seq[ref int] =
discard
template smokeTest(kkind: SyncQueueKind, start, finish: uint64,
chunkSize: uint64) =
var queue: SyncQueue[SomeTPeer]
var request: SyncRequest[SomeTPeer]
discard queue.push(request, getSlice())
for k in {SyncQueueKind.Forward}:
for item in [(uint64(1181), uint64(1399), 41'u64)]:
smokeTest(k, item[0], item[1], item[2])
|