diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index df2816a0e..2fff4a6f1 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -205,7 +205,7 @@ proc createNimCreatePromiseCall(prom, threadParam: PNode): PNode = let castExpr = newNodeIT(nkCast, prom.info, prom.typ) castExpr.add emptyNode castExpr.add callCodeGenProc("nimCreatePromise", threadParam, size) - result = newFastAsgnStmt(prom, castExpr) + result = castExpr proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; varSection, call, barrier, prom: PNode; @@ -216,9 +216,14 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; var threadLocalProm: PSym if spawnKind == srByVar: threadLocalProm = addLocalVar(varSection, argsParam.owner, prom.typ, prom) + elif prom != nil: + internalAssert prom.typ.kind == tyGenericInst + threadLocalProm = addLocalVar(varSection, argsParam.owner, prom.typ, + createNimCreatePromiseCall(prom, threadParam.newSymNode)) + body.add varSection if prom != nil and spawnKind != srByVar: - body.add createNimCreatePromiseCall(prom, threadParam.newSymNode) + body.add newFastAsgnStmt(prom, threadLocalProm.newSymNode) if barrier == nil: body.add callCodeGenProc("nimPromiseCreateCondVar", prom) @@ -230,10 +235,12 @@ proc createWrapperProc(f: PNode; threadParam, argsParam: PSym; if fk == promInvalid: localError(f.info, "cannot create a promise of type: " & typeToString(prom.typ.sons[1])) - body.add newAsgnStmt(indirectAccess(prom, + body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, if fk == promGC: "data" else: "blob", prom.info), call) if barrier == nil: - body.add callCodeGenProc("nimPromiseSignal", prom) + # by now 'prom' is shared and thus might have beeen overwritten! we need + # to use the thread-local view instead: + body.add callCodeGenProc("nimPromiseSignal", threadLocalProm.newSymNode) else: body.add call if barrier != nil: diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 24cb9ccdd..3a7693791 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -151,7 +151,7 @@ proc await*[T](prom: Promise[T]) = if prom.usesCondVar: await(prom.cv) proc awaitAndThen*[T](prom: Promise[T]; action: proc (x: T) {.closure.}) = - ## blocks until the value is available and then passes this value + ## blocks until the ``prom`` is available and then passes its value ## to ``action``. Note that due to Nimrod's parameter passing semantics this ## means that ``T`` doesn't need to be copied and so ``awaitAndThen`` can ## sometimes be more efficient than ``^``. diff --git a/tests/parallel/nimrod.cfg b/tests/parallel/nimrod.cfg new file mode 100644 index 000000000..b81c89721 --- /dev/null +++ b/tests/parallel/nimrod.cfg @@ -0,0 +1 @@ +threads:on