t21306.nim 3.1 KB

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