#!/usr/bin/env guile !# ;; Copyright Chris Vine 2014 and 2016 ;; ;; Permission is hereby granted, free of charge, to any person ;; obtaining a copy of this file (the "Software"), to deal in the ;; Software without restriction, including without limitation the ;; rights to use, copy, modify, merge, publish, distribute, ;; sublicense, and/or sell copies of the Software, and to permit ;; persons to whom the Software is furnished to do so, subject to the ;; following conditions: ;; ;; The above copyright notice and this permission notice shall be ;; included in all copies or substantial portions of the Software. ;; ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ;; SOFTWARE. ;; pick up our local modules (add-to-load-path (dirname (current-filename))) (use-modules (event-loop) (coroutines) (ice-9 threads)) (define main-loop (make-event-loop)) (event-post! main-loop (lambda () (a-sync (lambda (await resume) (display "In waitable procedure\n") ;; NOTE: we don't try to do it below, but you cannot run two ;; or more asynchronous tasks concurrently using the ;; await/resume technique with the same await-resume pair ;; without extra work, because the first call to 'await' ;; will match the first callback which happens to call ;; 'resume', and so on. In such cases, 'resume' would need ;; to return something like a key-value pair so that the ;; result can be correctly identified. ;; launch asynchronous task: let's pretend its time ;; consuming so we need to run it in a worker thread ;; to avoid blocking any other events in the main loop ;; (there aren't any in this example) (a-sync-run-task-in-thread (lambda () ;; do some work (usleep 500000) (display "In first async callback, work done\n") ;; this is the result of our extensive computation "Hello via async\n") main-loop resume) (display "About to make first wait\n") (display (string-append "Back in waitable procedure, and the callback says: " (await))) ;; launch another asynchronous task, this time in the event loop thread (event-post! main-loop (lambda () (display "In second async callback\n") (event-loop-quit! main-loop) (resume))) (display "About to make second wait\n") (await) (display "Quitting\n"))))) ;; because we are running tasks in another thread (event-loop-block! main-loop #t) (event-loop-run! main-loop)