about summary refs log tree commit diff stats
path: root/src/io
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-05-14 13:25:36 +0200
committerbptato <nincsnevem662@gmail.com>2023-05-14 13:25:36 +0200
commit58dee598d30c5d107f9c469eb01c660b39832f9a (patch)
tree3529a5b3499b33ad92ae394c22ad7782cf6fb7c1 /src/io
parent938bb0d0edd2a688e4ab9ca775b2d30ffb907d72 (diff)
downloadchawan-58dee598d30c5d107f9c469eb01c660b39832f9a.tar.gz
Async resource loading, exception handling fixes
Diffstat (limited to 'src/io')
-rw-r--r--src/io/http.nim5
-rw-r--r--src/io/promise.nim19
2 files changed, 23 insertions, 1 deletions
diff --git a/src/io/http.nim b/src/io/http.nim
index 60387faf..2eefb9ce 100644
--- a/src/io/http.nim
+++ b/src/io/http.nim
@@ -52,7 +52,10 @@ proc curlWriteHeader(p: cstring, size: csize_t, nitems: csize_t, userdata: point
   let op = cast[HandleData](userdata)
   if not op.statusline:
     op.statusline = true
-    op.ostream.swrite(int(CURLE_OK))
+    try:
+      op.ostream.swrite(int(CURLE_OK))
+    except IOError: # Broken pipe
+      return 0
     var status: int
     op.curl.getinfo(CURLINFO_RESPONSE_CODE, addr status)
     op.ostream.swrite(status)
diff --git a/src/io/promise.nim b/src/io/promise.nim
index 46825244..00702cec 100644
--- a/src/io/promise.nim
+++ b/src/io/promise.nim
@@ -1,10 +1,14 @@
 import tables
 
 type
+  PromiseState = enum
+    PROMISE_PENDING, PROMISE_FULFILLED, PROMISE_REJECTED
+
   EmptyPromise* = ref object of RootObj
     cb: (proc())
     next: EmptyPromise
     opaque: pointer
+    state: PromiseState
 
   Promise*[T] = ref object of EmptyPromise
     res: T
@@ -37,6 +41,7 @@ proc resolve*(promise: EmptyPromise) =
     if promise.cb != nil:
       promise.cb()
     promise.cb = nil
+    promise.state = PROMISE_FULFILLED
     promise = promise.next
     if promise == nil:
       break
@@ -62,6 +67,8 @@ proc then*(promise: EmptyPromise, cb: (proc())): EmptyPromise {.discardable.} =
   if promise == nil: return
   promise.cb = cb
   promise.next = EmptyPromise()
+  if promise.state == PROMISE_FULFILLED:
+    promise.resolve()
   return promise.next
 
 proc then*[T](promise: Promise[T], cb: (proc(x: T))): EmptyPromise {.discardable.} =
@@ -103,3 +110,15 @@ proc then*[T, U](promise: Promise[T], cb: (proc(x: T): Promise[U])): Promise[U]
         next.res = y
         next.resolve()))
   return next
+
+proc all*(promises: seq[EmptyPromise]): EmptyPromise =
+  let res = EmptyPromise()
+  var i = 0
+  for promise in promises:
+    promise.then(proc() =
+      inc i
+      if i == promises.len:
+        res.resolve())
+  if promises.len == 0:
+    res.resolve()
+  return res