Comments (3)
IIRC Win32 console handles do not support overlapped I/O, so any kind of asynchronous capability requires threads; the standard input and output streams are not opened with FILE_FLAG_OVERLAPPED
, and additional console handles opened using CreateFile
do not respect that flag
from crystal.
This snippet echoes the standard input while printing an asterisk every second in the background, using a dedicated thread for reading from STDIN
. It should work with or without -Dpreview_mt
, and with both redirected or console input:
require "colorize"
lib LibC
fun PostQueuedCompletionStatus(completionPort : HANDLE, dwNumberOfBytesTransferred : DWORD, dwCompletionKey : ULONG_PTR, lpOverlapped : OVERLAPPED*) : BOOL
end
module AsyncStdin
@@read_cv = Thread::ConditionVariable.new
@@read_mtx = Thread::Mutex.new
@@iocp : LibC::HANDLE = LibC::INVALID_HANDLE_VALUE
@@read_key = Crystal::IOCP::CompletionKey.new
@@done_cv = Thread::ConditionVariable.new
@@done_mtx = Thread::Mutex.new
@@buf : String?
@@stdin_read = Thread.new do
while true
@@read_mtx.synchronize do
until @@read_key.fiber
@@read_cv.wait(@@read_mtx)
end
end
# this shall be baked into `ConsoleUtils.read_console` instead, which also implies
# this entire thread shouldn't need to interact with any Crystal scheduler directly
@@buf = STDIN.gets.not_nil!
# `JOB_OBJECT_MSG_EXIT_PROCESS` is to reuse the resumption mechanism for `Process.run`
LibC.PostQueuedCompletionStatus(@@iocp, LibC::JOB_OBJECT_MSG_EXIT_PROCESS, @@read_key.object_id, nil)
@@done_mtx.synchronize do
while @@buf
@@done_cv.wait(@@done_mtx)
end
end
end
end
def self.read_stdin
@@read_mtx.synchronize do
# TODO: what happens if there are concurrent reads? replace these with a queue?
@@iocp = Crystal::EventLoop.current.iocp
@@read_key.fiber = Fiber.current
@@read_cv.signal
end
Fiber.suspend
@@done_mtx.synchronize do
buf, @@buf = @@buf, nil
@@done_cv.signal
buf
end
end
spawn do
while true
print '*'.colorize.magenta
sleep 1
end
end
while true
print read_stdin.colorize.green
end
end
from crystal.
I'm sure STDOUT
and STDERR
can be made non-blocking in a similar manner, but what differences would that make?
from crystal.
Related Issues (20)
- Store annotations within the node they annotate HOT 3
- Method overloads and type specificity are influenced by order of definition HOT 5
- Error: undefined method 'to_unsafe' for Foo (compile-time type is MyModule) HOT 4
- Filters do not work with dependencies tool on Windows HOT 1
- Zstd - "you've found a bug in the Crystal compiler. Please open an issue .. " HOT 2
- `XML::Error.errors` leaks memory HOT 16
- Nil assertion failed (NilAssertionError) HOT 2
- Setting instance variable of file-private type in def parameter breaks with restriction augmenter
- Error: can't restrict Array(A | B) to Array(A | B)
- Truncated quotient and remainder
- Loading debug symbols is not thread-safe on Windows HOT 2
- Inverse of `Int#digits`
- `Number#humanize` raises on infinity and NaN
- `bin\crystal run` wrapper does not terminate if interrupts are ignored HOT 4
- `Object#crystal_type_id` returns different value for virtual type in interpreter
- Typing of ivars does not play well with macros HOT 1
- Reduce CI usage
- Crystal compiler error: Element not found (Enumerable::NotFoundError)
- Crystal Compiler error: Module validation failed: GEP base pointer is not a vector or a vector of pointers HOT 1
- Incorrect function args when yield used in argument list HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from crystal.