t21306.nim 3.0 KB

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