Skip to content

Instantly share code, notes, and snippets.

@dom96
Created January 19, 2020 20:15
Show Gist options
  • Save dom96/a4f8754f646e95a03985fa91b56172c3 to your computer and use it in GitHub Desktop.
Save dom96/a4f8754f646e95a03985fa91b56172c3 to your computer and use it in GitHub Desktop.
import asyncdispatch, asyncfutures, strutils
proc asyncProc(): Future[string] =
var retFuture_404014 = newFuture[string]("asyncProc")
iterator asyncProcIter_404015(): owned(FutureBase) {.closure.} =
{.push, warning[resultshadowed]: off.}
var result: string
{.pop.}
complete(retFuture_404014, " green eggs and ham")
return nil
let retFutUnown = unown retFuture_404014
var nameIterVar = asyncProcIter_404015
proc asyncProcNimAsyncContinue_404016() {.closure.} =
try:
if not nameIterVar.finished:
var next = unown nameIterVar()
while (not next.isNil) and
next.finished:
next = unown nameIterVar()
if nameIterVar.finished:
break
if next ==
nil:
if not retFutUnown.finished:
let msg = "Async procedure ($1) yielded `nil`, are you await\'ing a " &
"`nil` Future?"
raise newException(AssertionError, msg % "asyncProc")
else:
{.gcsafe.}:
{.push, hint[ConvFromXtoItselfNotNeeded]: off.}
next.callback = (proc () {.closure, gcsafe.})(
asyncProcNimAsyncContinue_404016)
{.pop.}
except:
if retFutUnown.finished:
raise
else:
retFutUnown.fail(getCurrentException())
asyncProcNimAsyncContinue_404016()
return retFuture_404014
proc main() =
var fut = asyncProc()
var res = waitFor fut
assert res == " green eggs and ham"
main()
@Araq
Copy link

Araq commented Jan 19, 2020

import asyncdispatch, asyncfutures, strutils

proc asyncProc(): Future[string] =
  var retFuture_404014 = newFuture[string]("asyncProc")
  iterator asyncProcIter_404015(): owned(FutureBase) {.closure.} =
    {.push, warning[resultshadowed]: off.}
    var result: string
    {.pop.}
    complete(retFuture_404014, " green eggs and ham")
    return nil

  let retFutUnown {.cursor.} = retFuture_404014
  var nameIterVarOwner = asyncProcIter_404015
  var nameIterVar {.cursor.} = asyncProcIter_404015
  proc asyncProcNimAsyncContinue_404016() {.closure, gcsafe.} =
    try:
      if not nameIterVar.finished:
        var next = unown nameIterVar()
        while (not next.isNil) and
            next.finished:
          next = unown nameIterVar()
          if nameIterVar.finished:
            break
        if next ==
            nil:
          if not retFutUnown.finished:
            let msg = "Async procedure ($1) yielded `nil`, are you await\'ing a " &
                "`nil` Future?"
            raise newException(AssertionError, msg % "asyncProc")
        else:
          {.gcsafe.}:
            {.push, hint[ConvFromXtoItselfNotNeeded]: off.}
            next.callback = (proc () {.closure, gcsafe.})(
                asyncProcNimAsyncContinue_404016)
            {.pop.}

    except:
      if retFutUnown.finished:
        raise
      else:
        retFutUnown.fail(getCurrentException())

  asyncProcNimAsyncContinue_404016()
  return retFuture_404014

proc main() =
  var fut = asyncProc()
  var res = waitFor fut
  assert res == " green eggs and ham"

let startMem = getOccupiedMem()
main()
echo "Mem: ", (getOccupiedMem() - startMem)

This variant doesn't leak for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment