Skip to content

Instantly share code, notes, and snippets.

@wingo
Last active February 1, 2021 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wingo/74d9c708ef3d2c5e884df254e9392974 to your computer and use it in GitHub Desktop.
Save wingo/74d9c708ef3d2c5e884df254e9392974 to your computer and use it in GitHub Desktop.
;; Fibers: cooperative, event-driven user-space threads.
;;;; Copyright (C) 2016,2021 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 3 of the License, or (at your option) any later version.
;;;;
;;;; This library is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;;;;
(define-module (fd-readable-operations)
#:use-module (fibers scheduler)
#:use-module (fibers operations)
#:use-module (ice-9 atomic)
#:use-module (ice-9 match)
#:use-module (ice-9 threads)
#:export (wait-until-fd-readable-operation))
(define *poll-sched* (make-atomic-box #f))
(define (poll-sched)
(or (atomic-box-ref *poll-sched*)
(let ((sched (make-scheduler)))
(cond
((atomic-box-compare-and-swap! *poll-sched* #f sched))
(else
;; FIXME: Would be nice to clean up this thread at some point.
(call-with-new-thread
(lambda ()
(define (finished?) #f)
(run-scheduler sched finished?)))
sched)))))
(define (wait-until-port-readable-operation port)
"Make an operation that will succeed when PORT is readable."
(make-base-operation #f
(lambda ()
(and (char-ready? port)
values))
(lambda (flag sched resume)
(define (commit)
(match (atomic-box-compare-and-swap! flag 'W 'S)
('W (resume values))
('C (commit))
('S #f)))
(if sched
(schedule-task-when-fd-writable
sched (port-read-wait-fd port) commit)
(schedule-task
(poll-sched)
(lambda ()
(perform-operation (wait-until-port-readable-operation port))
(commit)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment