A soon as you type your channels you run into composability problems as you 
cannot easily wait for _either_ Channel[T1] or Channel[T2].

Rather than avoiding signals I would embrace them as a general purpose 
interrupt mechanism. And an interrupt can be scheduled on a different thread. 
And then I would base the entire API on top of it. This way everything is 
`async` in a natural fashion. The context switches become more visible in the 
code. No channels, sinks or sources required.

For example:
    
    
    proc requestReadOp() =
      var buf: SomeBuffer
      req(url = "somefile.txt", op = fmRead, mode = Blocking, env = addr(buf), 
oncomplete = proc (env: pointer, src: pointer, size: int) {.cdecl.} =
        copyMem env, src, size
      )
    
    
    
    Run

This way the OS only need to provide the callback based version. Well ... I 
suppose it's close enough to a traditional event loop.

Reply via email to