* io.c (rb_io_getline_fast): chomp CR followed by LF but separated
by the read buffer boundary. [ruby-core:91707] [Bug #15642]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67188 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
fixed r66930.
* io.c (nogvl_copy_stream_func): use fcopyfile(3) in IO.copy_stream if available
* configure.ac: check copyfile.h and fcopyfile(3)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66934 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* io.c (nogvl_copy_stream_func): use fcopyfile(3) in IO.copy_stream if available
* configure.ac: check copyfile.h and fcopyfile(3)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66930 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
There is no need to call this function twice in a row since
thread switching won't happen in-between calls to it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66244 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Since io_fflush may block on mutex or rb_io_wait_readable and
switch threads, we need to ensure the `str' VALUE returned by
`rb_obj_as_string` is visible to GC.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Especially over checking argc then calling rb_scan_args just to
raise an ArgumentError.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
On my 32-bit x86 userspace, I get the following .text savings:
text data bss dec hex filename
152971 56 252 153279 256bf io.o.before
152863 56 252 153171 25653 io.o.after
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66096 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
There seems to be a compatibility problems with Rails +
Rack::Deflater; so we revert this incompatibility.
This effectively reverts r65922; but keeps the bugfixes to
better support non-blocking sockets and pipes for future use.
[Bug #15356] [Bug #14968]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
On 64-bit Linux, fstat() needs to fill out a 144 byte struct
while F_GETFL only needs to return 8 bytes.
Fwiw, F_GETFD requires an additional rcu_read_lock and bitmap
check; so it's obviously more expensive than F_GETFL on Linux.
Reduce stack usage of rb_update_max_fd from 184 to 24 bytes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66060 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
nogvl_copy_file_range and nogvl_copy_stream_sendfile each
used 344 bytes of stack before this change. Now, they are
inlined into nogvl_copy_stream_func which only uses 200 bytes
of stack.
"struct stat" is 144 bytes on my 64-bit Linux.
Note: this doesn't affect GC (yet) since GVL is released;
but increases safety if called from deep machine stacks.
It will affect GC if Thread::Light is merged.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Reduce the struct to 80 bytes (from 88) on amd64 to reduce
stack use.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66049 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Lets admit Windows will always be too different from POSIX-like
platforms and non-blocking may never work as well or consistently.
[ruby-core:90042] [ruby-core:90044] [Bug #14968]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65962 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Since non-blocking I/O is the default after [Bug #14968],
we will hit it more often and cause more acquisition/release
of GVL to wait on single FD.
This also lets us avoid touching the temporal string locking
as much and lets us clean up some test changes made for
[Bug #14968]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65948 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This may fix failures from TestIO#test_recycled_fd_close because
interrupts may be missed due to TOCTOU in other places.
cf. http://ci.rvm.jp/results/trunk-nopara@silicon-docker/1475034
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65939 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The previous ordering was:
a) notify waiting_fd threads of impending close
b) waiting on busy list from a)
c) invalidate fptr->fd
d) calling close()
However, it was possible for a new thread to enter
the waiting_fd list while scheduling on b), leading
to EBADF from those threads when we hit d).
Instead, we now avoid triggering EBADF in other threads by
reordering b) and c)
a) notify waiting_fd threads of impending close
c) invalidate fptr->fd
b) waiting on busy list from a)
d) calling close()
cf. http://ci.rvm.jp/results/trunk-nopara@silicon-docker/1474526
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
fptr->fd may become -1 while GVL is released in
rb_wait_for_single_fd, so we must check it after reacquiring
GVL. This should avoid EBADF errors exposed by making pipes
non-blocking by default:
http://ci.rvm.jp/results/trunk-test@ruby-sky3/1473710
[Bug #14968]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65931 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
All normal Ruby IO methods (IO#read, IO#gets, IO#write, ...) are
all capable of appearing to be "blocking" when presented with a
file description with the O_NONBLOCK flag set; so there is
little risk of incompatibility within Ruby-using programs.
The biggest compatibility risk is when spawning external
programs. As a result, stdin, stdout, and stderr are now always
made blocking before exec-family calls.
This change will make an event-oriented MJIT usable if it is
waiting on pipes on POSIX_like platforms.
It is ALSO necessary to take advantage of (proposed lightweight
concurrency (aka "auto-Fiber") or any similar proposal for
network concurrency: https://bugs.ruby-lang.org/issues/13618
Named-pipe (FIFO) are NOT yet non-blocking by default since
they are rarely-used and may introduce compatibility problems
and extra syscall overhead for a common path.
Please revert this commit if there are problems and if I am afk
since I am afk a lot, lately.
[ruby-core:89950] [Bug #14968]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The behaviour of IO#ungetbyte has been depending on the width of
Fixnums. Fixnums should be invisible nowadays. It must be a
bug. Fix [Bug #14359]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65802 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This respects VM_CHECK_MODE and is more consistent with
the rest of our code.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65777 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The former states explicitly that the argument must be a literal,
and can optimize away `strlen` on all compilers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* io.c (argf_next_argv): convert filename to the OS encoding to be
dealt with by system calls. [ruby-dev:50607] [Bug #14970]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64243 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
GNU/Hurd has writev(2) but does not define IOV_MAX
[ruby-core:87417] [Bug #14827]
Reported-by: Paul Sonnenschein
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
FreeBSD 11.0+ supports ppoll, so we may use it after accounting
for portability differences in how it treats POLLOUT vs POLLHUP
events as mutually exclusive (as documented in the FreeBSD
poll(2) manpage).
For waiting on high-numbered single FDs, this should put
FreeBSD on equal footing with Linux and should allow cheaper
FD readiness checking with sleepy GC in the future.
* thread.c (USE_POLL, POLLERR_SET): define for FreeBSD 11.0+
(rb_wait_for_single_fd): return all requested events on POLLERR_SET
io.c (USE_POLL): define for FreeBSD 11.0+
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
However this function is listed in ruby/io.h. We cannot but
define a new, void-returning variant to use instead.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
While we cannot use LIST_HEAD since r63312, we can at
least use list_head_init to make our code more readable.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63314 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Address of a variable whose storage duration is `auto` is _not_ a
compile time constant, according to ISO 9899 section 6.4.
LIST_HEAD takes such thing. You can't use it to declare local
variables.
Interestingly, address of a static variable _is_ a compile time
constant. So a declaration like `static LIST_HEAD..` is
completely legal even in C90.
In C99 and newer, this is not a constraint violation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63312 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* io.c (internal_write_func, internal_writev_func): retry at
unexpected EPROTOTYPE on macOS, to get rid of a kernel bug.
[ruby-core:86690] [Bug #14713]
* ext/socket/init.c (rsock_{sendto,send,write}_blocking): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63304 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It is unsafe to release GVL and call rb_notify_fd_close after
close(2) on any given FD. FDs (file descriptor) may be recycled
in other threads immediately after close() to point to a different
file description. Note the distinction between "file description"
and "file descriptor".
th-1 | th-2
-------------------------------+---------------------------------------
io_close_fptr |
rb_notify_fd_close(fd) |
fptr_finalize_flush |
close(fd) |
rb_thread_schedule |
| fd reused (via pipe/open/socket/etc)
rb_notify_fd_close(fd) |
| sees "stream closed" exception
| for DIFFERENT file description
* thread.c (rb_thread_io_blocking_region): adjust comment for list_del
* thread.c (rb_notify_fd_close): give busy list to caller
* thread.c (rb_thread_fd_close): loop on busy list
* io.c (io_close_fptr): do not call rb_thread_fd_close on invalid FD
* io.c (io_reopen): use rb_thread_fd_close
Fixes: r57422 ("io.c: close before wait")
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63216 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This is consistent with other implementations of .write
in openssl and stringio.
* io.c (io_write_m): return 0 on argc == 0
[ruby-core:86285] [Bug #14338]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62967 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
For security reasons, File.read, File.binread, File.write, File.binwrite,
File.foreach, and File.readlines should not invoke external commands even
if the path starts with the pipe character |.
[ruby-core:84495] [Feature #14245]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62857 b2dd03c8-39d4-4d8f-98ff-823fe69b080e