Граф коммитов

1935 Коммитов

Автор SHA1 Сообщение Дата
Peter Zhu 5e0c171451 Make io_fwrite safe for compaction
[Bug #20169]

Embedded strings are not safe for system calls without the GVL because
compaction can cause pages to be locked causing the operation to fail
with EFAULT. This commit changes io_fwrite to use rb_str_tmp_frozen_no_embed_acquire,
which guarantees that the return string is not embedded.
2024-02-05 11:11:07 -05:00
Samuel Williams 2554c5d3b8
Don't wait in `io_binwrite_string` if not necessary. (#9792) 2024-02-01 15:27:44 +13:00
Nobuyoshi Nakada d86c4e553e
Define `IO_WITHOUT_GVL` macro 2024-01-24 20:51:50 +09:00
Burdette Lamar ef685554c9
[DOC] RDoc for ARGF (#9558) 2024-01-18 10:15:25 -05:00
Xavier Noria aad246feba s/SafeStringValue/StringValue/
The macro SafeStringValue() became just StringValue() in c5c05460ac,
and it is deprecated nowadays.

This patch replaces remaining macro usage. Some occurrences are left in
ext/stringio and ext/win32ole, they should be fixed upstream.

The macro itself is not deleted, because it may be used in extensions.
2024-01-12 12:24:48 -08:00
S.H a6ba45e9b0
Remove unnecessary semicolons (#9469) 2024-01-10 16:21:55 -08:00
KJ Tsanaktsidis 31371b2e24 Fix CRLF -> LF conversion on read for rb_io_fdopen & rb_file_open
When opening a file with `File.open`, and then setting the encoding with
`IO#set_encoding`, it still correctly performs CRLF -> LF conversion on
Windows when reading files with a CRLF line ending in them (in text
mode).

However, the file is opened instead with either the `rb_io_fdopen` or
`rb_file_open` APIs from C, the CRLF conversion is _NOT_ set up
correctly; it works if the encoding is not specified, but if
`IO#set_encoding` is called, the conversion stops happening. This seems
to be because the encflags never get ECONV_DEFAULT_NEWLINE_DECORATOR
set in these codepaths.

Concretely, this means that the conversion doesn't happen in the
following circumstances:
  * When loading ruby files with require (that calls rb_io_fdopen)
  * When parsing ruuby files with RubyVM::AbstractSyntaxTree (that calls
    rb_file_open).
This then causes the ErrorHighlight tests to fail on windows if git has
checked them out with CRLF line endings - the error messages it's
testing wind up with literal \r\n sequences in them because the iseq
text from the parser contains un-newline-converted strings.

This commit fixes the problem by copy-pasting the relevant snippet which
sets this up in `rb_io_extract_modeenc` (for the File.open path) into
the relevant codepaths for `rb_io_fdopen` and `rb_file_open`.

[Bug #20101]
2024-01-10 21:02:23 +11:00
Koichi Sasada d65d2fb6b5 Do not `poll` first
Before this patch, the MN scheduler waits for the IO with the
following steps:

1. `poll(fd, timeout=0)` to check fd is ready or not.
2. if fd is not ready, waits with MN thread scheduler
3. call `func` to issue the blocking I/O call

The advantage of advanced `poll()` is we can wait for the
IO ready for any fds. However `poll()` becomes overhead
for already ready fds.

This patch changes the steps like:

1. call `func` to issue the blocking I/O call
2. if the `func` returns `EWOULDBLOCK` the fd is `O_NONBLOCK`
   and we need to wait for fd is ready so that waits with MN
   thread scheduler.

In this case, we can wait only for `O_NONBLOCK` fds. Otherwise
it waits with blocking operations such as `read()` system call.
However we don't need to call `poll()` to check fd is ready
in advance.

With this patch we can observe performance improvement
on microbenchmark which repeats blocking I/O (not
`O_NONBLOCK` fd) with and without MN thread scheduler.

```ruby
require 'benchmark'

f = open('/dev/null', 'w')
f.sync = true

TN = 1
N = 1_000_000 / TN

Benchmark.bm{|x|
  x.report{
    TN.times.map{
      Thread.new{
        N.times{f.print '.'}
      }
    }.each(&:join)
  }
}
__END__
TN = 1
                 user     system      total        real
ruby32       0.393966   0.101122   0.495088 (  0.495235)
ruby33       0.493963   0.089521   0.583484 (  0.584091)
ruby33+MN    0.639333   0.200843   0.840176 (  0.840291) <- Slow
this+MN      0.512231   0.099091   0.611322 (  0.611074) <- Good
```
2024-01-05 05:51:25 +09:00
Koichi Sasada beec3d07c9 MN: skip waiting on `read_nonblock'
if the IO for `IO#read_nonblock` is not ready, it needs
to return (or raise) immediately.
2023-12-23 08:10:41 +09:00
Koichi Sasada 7a0dfdea8c use `rb_thread_io_blocking_call()` more
use `rb_thread_io_blocking_call()` instead of
`rb_thread_io_blocking_region()` more.

See https://github.com/ruby/ruby/pull/9178#issuecomment-1858711533
2023-12-20 07:00:41 +09:00
Nobuyoshi Nakada e9b0b6015e
[DOC] Add documents of constants for IO#wait event mask 2023-12-18 20:17:44 +09:00
Ryan Davis 6ecc1ca9b1
[DOC] Update ARGF.readlines documentation to match/reference IO.readlines. 2023-12-01 22:51:08 +00:00
Jean Boussier b013aae0c6 IO#read always check the provided buffer is mutable
Otherwise you can have work in some circumstance but not in others.
2023-11-09 11:45:02 +01:00
Charles Oliver Nutter 55d954721e
Raise TypeError for bad IO::Buffer.map argument (#8728)
* Raise TypeError when IO::Buffer.map argument is neither IO nor implements #fileno

* Use UNREACHABLE_CODE

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>

* Use macro for undef check

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>

---------

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2023-10-21 17:30:40 +13:00
Herwin cd0b8d2441
[DOC] Fix typo in docs of IO: `#.` -> `$.` 2023-10-04 23:02:08 +09:00
Aaron Patterson d3574c117a Move IO#readline to Ruby
This commit moves IO#readline to Ruby.  In order to call C functions,
keyword arguments must be converted to hashes.  Prior to this commit,
code like `io.readline(chomp: true)` would allocate a hash.  This
commits moves the keyword "denaturing" to Ruby, allowing us to send
positional arguments to the C API and avoiding the hash allocation.

Here is an allocation benchmark for the method:

```
x = GC.stat(:total_allocated_objects)
File.open("/usr/share/dict/words") do |f|
  f.readline(chomp: true) until f.eof?
end
p ALLOCATIONS: GC.stat(:total_allocated_objects) - x
```

Before this commit, the output was this:

```
$ make run
./miniruby -I./lib -I. -I.ext/common  -r./arm64-darwin22-fake  ./test.rb
{:ALLOCATIONS=>707939}
```

Now it is this:

```
$ make run
./miniruby -I./lib -I. -I.ext/common  -r./arm64-darwin22-fake  ./test.rb
{:ALLOCATIONS=>471962}
```

[Bug #19890] [ruby-core:114803]
2023-09-28 10:43:45 -07:00
Nobuyoshi Nakada 7e2775b057 Invoke the command when RUBY_BUGREPORT_PATH starts with `|` 2023-09-25 22:57:28 +09:00
Nobuyoshi Nakada ab637cad2b [Bug #19624] Clean up backquote IO
It should not be hidden, since it can be grabbed by a fiber scheduler.
2023-09-21 10:23:14 +09:00
Nobuyoshi Nakada 72772a3caa [DOC] Mention "-" in ARGF 2023-09-17 22:05:58 +09:00
Herwin b926ac51cc
[DOC] Fix a typo in "Open Options" section of IO
The word "and" was missing.
2023-09-10 19:33:48 +09:00
Herwin f867e936a9
[DOC] Fix layout in documentation of IO#fcntl 2023-09-03 01:49:40 +09:00
Jeremy Evans ae609a995e Document that Kernel#p is for debugging and may be uninterruptible [ci skip]
Fixes [Bug #18810]
2023-08-30 21:21:02 +01:00
Nobuyoshi Nakada 00ac3a64ba Introduce `at_char_boundary` function 2023-08-26 08:58:02 +09:00
Nobuyoshi Nakada 7d3634a121
Extract GC for fd parts as `TRY_WITH_GC ` 2023-08-16 22:53:00 +09:00
Nobuyoshi Nakada f0edcd8283
Extract platform dependent part as `fdopen_internal` 2023-08-16 22:53:00 +09:00
BurdetteLamar 546c5cfe4c [DOC] Don't suppress autolinks 2023-08-12 13:04:04 -04:00
Mike Dalessio d2343368ab Deprecate Kernel#open and IO support for subprocess creation/forking
Deprecate Kernel#open and IO support for subprocess creation and
forking. This deprecates subprocess creation and forking in

- Kernel#open
- URI.open
- IO.binread
- IO.foreach
- IO.readlines
- IO.read
- IO.write

This behavior is slated to be removed in Ruby 4.0

[Feature #19630]
2023-08-10 09:38:11 +09:00
Nobuyoshi Nakada c8d0470bb0
Use `File::NULL` instead of hard coded null device names 2023-07-10 19:21:47 +09:00
Burdette Lamar 6528cf9fcf
[DOC] Fixes for link fragments (#7981) 2023-06-28 09:05:43 -04:00
Nobuyoshi Nakada 46583f7dcf
Adjust style [ci skip] 2023-06-07 10:10:08 +09:00
Samuel Williams b7ee51e81d
Expose `enum rb_io_event` flags without `_t` suffix. (#7887) 2023-06-01 22:54:08 +09:00
Samuel Williams 47a8de6095
Drop `_t` suffix from struct names. (#7886)
POSIX reserves `_t` suffix in types.
2023-06-01 21:46:10 +09:00
KJ Tsanaktsidis edee9b6a12
Use a real Ruby mutex in rb_io_close_wait_list (#7884)
Because a thread calling IO#close now blocks in a native condvar wait,
it's possible for there to be _no_ threads left to actually handle
incoming signals/ubf calls/etc.

This manifested as failing tests on Solaris 10 (SPARC), because:

* One thread called IO#close, which sent a SIGVTALRM to the other
  thread to interrupt it, and then waited on the condvar to be notified
  that the reading thread was done.
* One thread was calling IO#read, but it hadn't yet reached the actual
  call to select(2) when the SIGVTALRM arrived, so it never unblocked
  itself.

This results in a deadlock.

The fix is to use a real Ruby mutex for the close lock; that way, the
closing thread goes into sigwait-sleep and can keep trying to interrupt
the select(2) thread.

See the discussion in: https://github.com/ruby/ruby/pull/7865/
2023-06-01 17:37:18 +09:00
Samuel Williams a218ed5692
Hide the usage of `rb_io_t` where possible. (#7880)
This retries the compatible parts of the previously reverted PR so we can continue to update related code without breaking backwards compatibility.
2023-06-01 14:23:30 +09:00
NARUSE, Yui 85dcc4866d Revert "Hide most of the implementation of `struct rb_io`. (#6511)"
This reverts commit 18e55fc1e1.

fix [Bug #19704]
https://bugs.ruby-lang.org/issues/19704
This breaks compatibility for extension libraries. Such changes
need a discussion.
2023-06-01 08:43:22 +09:00
Samuel Williams 18e55fc1e1
Hide most of the implementation of `struct rb_io`. (#6511)
* Add rb_io_path and rb_io_open_descriptor.

* Use rb_io_open_descriptor to create PTY objects

* Rename FMODE_PREP -> FMODE_EXTERNAL and expose it

FMODE_PREP I believe refers to the concept of a "pre-prepared" file, but
FMODE_EXTERNAL is clearer about what the file descriptor represents and
aligns with language in the IO::Buffer module.

* Ensure that rb_io_open_descriptor closes the FD if it fails

If FMODE_EXTERNAL is not set, then it's guaranteed that Ruby will be
responsible for closing your file, eventually, if you pass it to
rb_io_open_descriptor, even if it raises an exception.

* Rename IS_EXTERNAL_FD -> RUBY_IO_EXTERNAL_P

* Expose `rb_io_closed_p`.

* Add `rb_io_mode` to get IO mode.

---------

Co-authored-by: KJ Tsanaktsidis <ktsanaktsidis@zendesk.com>
2023-05-30 10:02:40 +09:00
Samuel Williams bf1bc5362e
Improve `read`/`write`/`pread`/`pwrite` consistency. (#7860)
* Documentation consistency.

* Improve consistency of `pread`/`pwrite` implementation when given length.

* Remove HAVE_PREAD / HAVE_PWRITE - it is no longer optional.
2023-05-27 18:48:47 +09:00
KJ Tsanaktsidis 66871c5a06 Fix busy-loop when waiting for file descriptors to close
When one thread is closing a file descriptor whilst another thread is
concurrently reading it, we need to wait for the reading thread to be
done with it to prevent a potential EBADF (or, worse, file descriptor
reuse).

At the moment, that is done by keeping a list of threads still using the
file descriptor in io_close_fptr. It then continually calls
rb_thread_schedule() in fptr_finalize_flush until said list is empty.

That busy-looping seems to behave rather poorly on some OS's,
particulary FreeBSD. It can cause the TestIO#test_race_gets_and_close
test to fail (even with its very long 200 second timeout) because the
closing thread starves out the using thread.

To fix that, I introduce the concept of struct rb_io_close_wait_list; a
list of threads still using a file descriptor that we want to close. We
call `rb_notify_fd_close` to let the thread scheduler know we're closing
a FD, which fills the list with threads. Then, we call
rb_notify_fd_close_wait which will block the thread until all of the
still-using threads are done.

This is implemented with a condition variable sleep, so no busy-looping
is required.
2023-05-26 14:51:23 +09:00
Samuel Williams 0b2613f443
`rb_io_puts` should not write zero length strings. (#7806) 2023-05-15 11:13:51 +09:00
Nobuyoshi Nakada 814f52a9eb [Bug #19624] Hide internal IO for backquote 2023-05-01 05:10:34 +09:00
Nobuyoshi Nakada 86db7a1cb8
[DOC] Fix typos 2023-04-13 13:28:47 +09:00
Nobuyoshi Nakada e13575bb79
[Bug #19584] Register global variables before assignment 2023-04-07 11:53:36 +09:00
Matt Valentine-House 026321c5b9 [Feature #19474] Refactor NEWOBJ macros
NEWOBJ_OF is now our canonical newobj macro. It takes an optional ec
2023-04-06 11:07:16 +01:00
Samuel Williams 648870b5c5
Support `IO#pread` / `IO#pwrite` using fiber scheduler. (#7594)
* Skip test if non-blocking file IO is not supported.
2023-03-31 00:48:55 +13:00
Jeremy Evans 6c60006de5 Raise ArgumentError if IO.read is provided negative offset
Fixes [Bug #19380]
2023-03-24 12:29:00 -07:00
Lars Kanis 47f8bf50e1 [DOC] Clarify IO#autoclose impact on #close
Mention that autoclose changes the behavior of explicit close in addition to implicit close at IO finalization.
2023-03-01 16:02:11 +09:00
John Bampton c43fbe4ebd
Fix spelling (#7405) 2023-02-28 10:05:30 -08:00
Nobuyoshi Nakada ef00c6da88
Adjust `else` style to be consistent in each files [ci skip] 2023-02-26 13:20:43 +09:00
BurdetteLamar 3b239d2480 Remove (newly unneeded) remarks about aliases 2023-02-19 14:26:34 -08:00
zverok 4f049e915d [DOC] Document IO::Timeout 2023-02-19 22:32:52 +02:00