ttasks.nim 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. discard """
  2. targets: "c cpp"
  3. matrix: "--gc:orc --threads:off"
  4. """
  5. import std/[tasks, strformat]
  6. import std/assertions
  7. block:
  8. var s = ""
  9. proc `+`(x: int, y: string) =
  10. s.add $x & y
  11. let literal = "Nim"
  12. let t = toTask(521 + literal)
  13. t.invoke()
  14. doAssert s == "521Nim"
  15. block:
  16. var s = ""
  17. proc `!`(x: int) =
  18. s.add $x
  19. let t = toTask !12
  20. t.invoke()
  21. doAssert s == "12"
  22. block:
  23. block:
  24. var called = 0
  25. proc hello(x: static range[1 .. 5]) =
  26. called += x
  27. let b = toTask hello(3)
  28. b.invoke()
  29. doAssert called == 3
  30. b.invoke()
  31. doAssert called == 6
  32. block:
  33. var called = 0
  34. proc hello(x: range[1 .. 5]) =
  35. called += x
  36. let b = toTask hello(3)
  37. b.invoke()
  38. doAssert called == 3
  39. b.invoke()
  40. doAssert called == 6
  41. block:
  42. var called = 0
  43. proc hello(x: 1 .. 5) =
  44. called += x
  45. let b = toTask hello(3)
  46. b.invoke()
  47. doAssert called == 3
  48. b.invoke()
  49. doAssert called == 6
  50. block:
  51. var temp = ""
  52. proc hello(a: int or seq[string]) =
  53. when a is seq[string]:
  54. for s in a:
  55. temp.add s
  56. else:
  57. temp.addInt a
  58. let x = @["1", "2", "3", "4"]
  59. let b = toTask hello(x)
  60. b.invoke()
  61. doAssert temp == "1234"
  62. b.invoke()
  63. doAssert temp == "12341234"
  64. block:
  65. var temp = ""
  66. proc hello(a: int or string) =
  67. when a is string:
  68. temp.add a
  69. let x = "!2"
  70. let b = toTask hello(x)
  71. b.invoke()
  72. doAssert temp == x
  73. block:
  74. var temp = ""
  75. proc hello(a: int or string) =
  76. when a is string:
  77. temp.add a
  78. let x = "!2"
  79. let b = toTask hello(x)
  80. b.invoke()
  81. doAssert temp == x
  82. block:
  83. var x = 0
  84. proc hello(typ: typedesc) =
  85. x += typ(12)
  86. let b = toTask hello(int)
  87. b.invoke()
  88. doAssert x == 12
  89. block:
  90. var temp = ""
  91. proc hello(a: int or seq[string]) =
  92. when a is seq[string]:
  93. for s in a:
  94. temp.add s
  95. let x = @["1", "2", "3", "4"]
  96. let b = toTask hello(x)
  97. b.invoke()
  98. doAssert temp == "1234"
  99. block:
  100. var temp = ""
  101. proc hello(a: int | string) =
  102. when a is string:
  103. temp.add a
  104. let x = "!2"
  105. let b = toTask hello(x)
  106. b.invoke()
  107. doAssert temp == x
  108. block:
  109. var x = 0
  110. proc hello(a: int | string) =
  111. when a is int:
  112. x = a
  113. let b = toTask hello(12)
  114. b.invoke()
  115. doAssert x == 12
  116. block:
  117. var a1: seq[int]
  118. var a2 = 0
  119. proc hello(c: seq[int], a: int) =
  120. a1 = c
  121. a2 = a
  122. let x = 12
  123. var y = @[1, 3, 1, 4, 5, x, 1]
  124. let b = toTask hello(y, 12)
  125. b.invoke()
  126. doAssert a1 == y
  127. doAssert a2 == x
  128. block:
  129. var a1: seq[int]
  130. var a2 = 0
  131. proc hello(c: seq[int], a: int) =
  132. a1 = c
  133. a2 = a
  134. var x = 2
  135. let b = toTask hello(@[1, 3, 1, 4, 5, x, 1], 12)
  136. b.invoke()
  137. doAssert a1 == @[1, 3, 1, 4, 5, x, 1]
  138. doAssert a2 == 12
  139. block:
  140. var a1: array[7, int]
  141. var a2 = 0
  142. proc hello(c: array[7, int], a: int) =
  143. a1 = c
  144. a2 = a
  145. let b = toTask hello([1, 3, 1, 4, 5, 2, 1], 12)
  146. b.invoke()
  147. doAssert a1 == [1, 3, 1, 4, 5, 2, 1]
  148. doAssert a2 == 12
  149. block:
  150. var a1: seq[int]
  151. var a2 = 0
  152. proc hello(c: seq[int], a: int) =
  153. a1 = c
  154. a2 = a
  155. let b = toTask hello(@[1, 3, 1, 4, 5, 2, 1], 12)
  156. b.invoke()
  157. doAssert a1 == @[1, 3, 1, 4, 5, 2, 1]
  158. doAssert a2 == 12
  159. block:
  160. var a1: seq[int]
  161. var a2 = 0
  162. proc hello(a: int, c: seq[int]) =
  163. a1 = c
  164. a2 = a
  165. let b = toTask hello(8, @[1, 3, 1, 4, 5, 2, 1])
  166. b.invoke()
  167. doAssert a1 == @[1, 3, 1, 4, 5, 2, 1]
  168. doAssert a2 == 8
  169. let c = toTask 8.hello(@[1, 3, 1, 4, 5, 2, 1])
  170. c.invoke()
  171. doAssert a1 == @[1, 3, 1, 4, 5, 2, 1]
  172. doAssert a2 == 8
  173. block:
  174. var a1: seq[seq[int]]
  175. var a2: int
  176. proc hello(a: int, c: openArray[seq[int]]) =
  177. a1 = @c
  178. a2 = a
  179. let b = toTask hello(8, @[@[3], @[4], @[5], @[6], @[12], @[7]])
  180. b.invoke()
  181. doAssert a1 == @[@[3], @[4], @[5], @[6], @[12], @[7]]
  182. doAssert a2 == 8
  183. block:
  184. var a1: seq[int]
  185. var a2: int
  186. proc hello(a: int, c: openArray[int]) =
  187. a1 = @c
  188. a2 = a
  189. let b = toTask hello(8, @[3, 4, 5, 6, 12, 7])
  190. b.invoke()
  191. doAssert a1 == @[3, 4, 5, 6, 12, 7]
  192. doAssert a2 == 8
  193. block:
  194. var a1: seq[int]
  195. var a2: int
  196. proc hello(a: int, c: static varargs[int]) =
  197. a1 = @c
  198. a2 = a
  199. let b = toTask hello(8, @[3, 4, 5, 6, 12, 7])
  200. b.invoke()
  201. doAssert a1 == @[3, 4, 5, 6, 12, 7]
  202. doAssert a2 == 8
  203. block:
  204. var a1: seq[int]
  205. var a2: int
  206. proc hello(a: int, c: static varargs[int]) =
  207. a1 = @c
  208. a2 = a
  209. let b = toTask hello(8, [3, 4, 5, 6, 12, 7])
  210. b.invoke()
  211. doAssert a1 == @[3, 4, 5, 6, 12, 7]
  212. doAssert a2 == 8
  213. block:
  214. var a1: seq[int]
  215. var a2: int
  216. proc hello(a: int, c: varargs[int]) =
  217. a1 = @c
  218. a2 = a
  219. let x = 12
  220. let b = toTask hello(8, 3, 4, 5, 6, x, 7)
  221. b.invoke()
  222. doAssert a1 == @[3, 4, 5, 6, 12, 7]
  223. doAssert a2 == 8
  224. block:
  225. var x = 12
  226. proc hello(x: ptr int) =
  227. x[] += 12
  228. let b = toTask hello(addr x)
  229. b.invoke()
  230. doAssert x == 24
  231. let c = toTask x.addr.hello
  232. invoke(c)
  233. doAssert x == 36
  234. block:
  235. type
  236. Test = ref object
  237. id: int
  238. var x = 0
  239. proc hello(a: int, c: static Test) =
  240. x += a
  241. x += c.id
  242. let b = toTask hello(8, Test(id: 12))
  243. b.invoke()
  244. doAssert x == 20
  245. block:
  246. type
  247. Test = object
  248. id: int
  249. var x = 0
  250. proc hello(a: int, c: static Test) =
  251. x += a
  252. x += c.id
  253. let b = toTask hello(8, Test(id: 12))
  254. b.invoke()
  255. doAssert x == 20
  256. block:
  257. var x = 0
  258. proc hello(a: int, c: static seq[int]) =
  259. x += a
  260. for i in c:
  261. x += i
  262. let b = toTask hello(8, @[3, 4, 5, 6, 12, 7])
  263. b.invoke()
  264. doAssert x == 45
  265. block:
  266. var x = 0
  267. proc hello(a: int, c: static array[5, int]) =
  268. x += a
  269. for i in c:
  270. x += i
  271. let b = toTask hello(8, [3, 4, 5, 6, 12])
  272. b.invoke()
  273. doAssert x == 38
  274. block:
  275. var aVal = 0
  276. var cVal = ""
  277. proc hello(a: int, c: static string) =
  278. aVal += a
  279. cVal.add c
  280. var x = 1314
  281. let b = toTask hello(x, "hello")
  282. b.invoke()
  283. doAssert aVal == x
  284. doAssert cVal == "hello"
  285. block:
  286. var aVal = ""
  287. proc hello(a: static string) =
  288. aVal.add a
  289. let b = toTask hello("hello")
  290. b.invoke()
  291. doAssert aVal == "hello"
  292. block:
  293. var aVal = 0
  294. var cVal = ""
  295. proc hello(a: static int, c: static string) =
  296. aVal += a
  297. cVal.add c
  298. let b = toTask hello(8, "hello")
  299. b.invoke()
  300. doAssert aVal == 8
  301. doAssert cVal == "hello"
  302. block:
  303. var aVal = 0
  304. var cVal = 0
  305. proc hello(a: static int, c: int) =
  306. aVal += a
  307. cVal += c
  308. let b = toTask hello(c = 0, a = 8)
  309. b.invoke()
  310. doAssert aVal == 8
  311. doAssert cVal == 0
  312. block:
  313. var aVal = 0
  314. var cVal = 0
  315. proc hello(a: int, c: static int) =
  316. aVal += a
  317. cVal += c
  318. let b = toTask hello(c = 0, a = 8)
  319. b.invoke()
  320. doAssert aVal == 8
  321. doAssert cVal == 0
  322. block:
  323. var aVal = 0
  324. var cVal = 0
  325. proc hello(a: static int, c: static int) =
  326. aVal += a
  327. cVal += c
  328. let b = toTask hello(0, 8)
  329. b.invoke()
  330. doAssert aVal == 0
  331. doAssert cVal == 8
  332. block:
  333. var temp = ""
  334. proc hello(x: int, y: seq[string], d = 134) =
  335. temp = fmt"{x=} {y=} {d=}"
  336. proc main() =
  337. var x = @["23456"]
  338. let t = toTask hello(2233, x)
  339. t.invoke()
  340. doAssert temp == """x=2233 y=@["23456"] d=134"""
  341. main()
  342. block:
  343. var temp = ""
  344. proc hello(x: int, y: seq[string], d = 134) =
  345. temp.add fmt"{x=} {y=} {d=}"
  346. proc ok() =
  347. temp = "ok"
  348. proc main() =
  349. var x = @["23456"]
  350. let t = toTask hello(2233, x)
  351. t.invoke()
  352. t.invoke()
  353. doAssert temp == """x=2233 y=@["23456"] d=134x=2233 y=@["23456"] d=134"""
  354. main()
  355. var x = @["4"]
  356. let m = toTask hello(2233, x, 7)
  357. m.invoke()
  358. doAssert temp == """x=2233 y=@["23456"] d=134x=2233 y=@["23456"] d=134x=2233 y=@["4"] d=7"""
  359. let n = toTask ok()
  360. n.invoke()
  361. doAssert temp == "ok"
  362. block:
  363. var called = 0
  364. block:
  365. proc hello() =
  366. inc called
  367. let a = toTask hello()
  368. invoke(a)
  369. doAssert called == 1
  370. block:
  371. proc hello(a: int) =
  372. inc called, a
  373. let b = toTask hello(13)
  374. let c = toTask hello(a = 14)
  375. b.invoke()
  376. c.invoke()
  377. doAssert called == 28
  378. block:
  379. proc hello(a: int, c: int) =
  380. inc called, a
  381. let b = toTask hello(c = 0, a = 8)
  382. b.invoke()
  383. doAssert called == 36
  384. block:
  385. proc returnsSomething(a, b: int): int = a + b
  386. proc noArgsButReturnsSomething(): string = "abcdef"
  387. proc testReturnValues() =
  388. let t = toTask returnsSomething(2233, 11)
  389. var res: int = 0
  390. t.invoke(addr res)
  391. doAssert res == 2233+11
  392. let tb = toTask noArgsButReturnsSomething()
  393. var resB: string = ""
  394. tb.invoke(addr resB)
  395. doAssert resB == "abcdef"
  396. testReturnValues()
  397. block: # bug #23635
  398. block:
  399. type
  400. Store = object
  401. run: proc (a: int) {.nimcall, gcsafe.}
  402. block:
  403. var count = 0
  404. proc hello(a: int) =
  405. inc count, a
  406. var store = Store()
  407. store.run = hello
  408. let b = toTask store.run(13)
  409. b.invoke()
  410. doAssert count == 13
  411. block:
  412. type
  413. Store = object
  414. run: proc () {.nimcall, gcsafe.}
  415. block:
  416. var count = 0
  417. proc hello() =
  418. inc count, 1
  419. var store = Store()
  420. store.run = hello
  421. let b = toTask store.run()
  422. b.invoke()
  423. doAssert count == 1