Project

General

Profile

Feature #9323

IO#writev

Added by Glass_saga (Masaki Matsushita) almost 4 years ago. Updated 2 days ago.

Status:
Closed
Priority:
Normal
Target version:
[ruby-core:59408]

Description

I propose addition of IO#writev.
It enables gather output from multiple buffers.
If writev(2) is not available, IO#writev uses Array#join to emulate atomic write.

patch.diff (7.83 KB) patch.diff Glass_saga (Masaki Matsushita), 12/30/2013 10:08 PM
patch.diff (6.28 KB) patch.diff Glass_saga (Masaki Matsushita), 06/27/2017 05:05 AM
patch.diff (6.79 KB) patch.diff IO#write accepts multiple arguments Glass_saga (Masaki Matsushita), 10/21/2017 12:20 PM

Related issues

Related to Ruby trunk - Feature #9420: warn and puts should be atomicOpen2014-01-15
Related to Ruby trunk - Feature #14042: IO#puts: use writev if availableOpen

Associated revisions

Revision 60343
Added by glass 2 days ago

Make IO#write accept multiple arguments

io.c: make IO#write accept multiple arguments.
it uses writev(2) if possible.

Revision 60351
Added by nobu (Nobuyoshi Nakada) 2 days ago

io.c: fix local variables

  • io.c (io_writev): fix local variable declarations, when writev(2) is not available. [Feature #9323]

Revision 60370
Added by nobu (Nobuyoshi Nakada) 1 day ago

io.c: no restriction

  • io.c (io_write_m): remove argc restriction upto IOV_MAX-1. [Feature #9323]

Revision 60371
Added by nobu (Nobuyoshi Nakada) 1 day ago

io.c: fix total

  • io.c (io_writev): total may be a bignum. [Feature #9323]

Revision 60372
Added by nobu (Nobuyoshi Nakada) 1 day ago

io.c: fix buffered output

  • io.c (io_binwritev): append to buffered data, not overwriting. [Feature #9323]

Revision 60373
Added by nobu (Nobuyoshi Nakada) 1 day ago

io.c: fix infinite retry

  • io.c (io_binwritev): fix infinite retry when flushing buffered data. [Feature #9323]

Revision 60376
Added by nobu (Nobuyoshi Nakada) 1 day ago

NEWS: add [Feature #9323] [ci skip]

History

#1 [ruby-core:60003] Updated by normalperson (Eric Wong) almost 4 years ago

Unless we have use for it, I don't think rb_io_writev should be in
the C API, and even less reason for it to be public for extensions
in ruby/intern.h

Also, it'd probably be good to dedup the fptr->wbuf initialization
code in io_binwrite*.

Otherwise, I think this is fine.

#2 [ruby-core:81567] Updated by ioquatix (Samuel Williams) 5 months ago

I think this is a great idea. It avoids a ton of string issues - e.g. concatenating strings in Ruby before writing them out. It would be great if #write could take an array, and if possible, call writev.

#4 Updated by Glass_saga (Masaki Matsushita) 4 months ago

  • Target version changed from 2.2.0 to 2.5

#5 [ruby-core:82020] Updated by Glass_saga (Masaki Matsushita) 3 months ago

It would be great if #write could take an array, and if possible, call writev.

That's would be nice.

File.open("test", "w") do |f|
  f.write("foo", "bar", "baz") # use writev(2) if possible
end

#6 [ruby-core:82979] Updated by akr (Akira Tanaka) 29 days ago

  • Status changed from Open to Feedback

Is there benchmark?

What the situation that writev is actually fast?

#7 [ruby-core:83013] Updated by Glass_saga (Masaki Matsushita) 28 days ago

The main purpose of IO#writev is to make a chance for users to write multiple buffers atomically, not to improve performance.

#8 [ruby-core:83014] Updated by normalperson (Eric Wong) 28 days ago

glass.saga@gmail.com wrote:

The main purpose of IO#writev is to make a chance for users to
write multiple buffers atomically, not to improve performance.

IO#write on Array#join result is atomic, too; but Array#join can
result in too large buffers and excessive memory use.

I wrote benchmarks for shards io-extra project on Rubyforge
years ago, but I guess that email is no longer available publically.
I've quoted and reposted the test to spew:

https://80x24.org/spew/20170926005509.GA22313@starla/raw

#9 [ruby-core:83373] Updated by matz (Yukihiro Matsumoto) 5 days ago

I vote for making IO#write take multiple arguments, probably using writev(2) inside.

Matz

#10 [ruby-core:83459] Updated by Glass_saga (Masaki Matsushita) 3 days ago

  • Assignee set to Glass_saga (Masaki Matsushita)
  • Status changed from Feedback to Assigned
  • File patch.diff patch.diff added

This patch makes IO#write accept multiple arguments.

#11 Updated by nobu (Nobuyoshi Nakada) 2 days ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r60351.


io.c: fix local variables

  • io.c (io_writev): fix local variable declarations, when writev(2) is not available. [Feature #9323]

#12 Updated by shyouhei (Shyouhei Urabe) 1 day ago

#13 Updated by shyouhei (Shyouhei Urabe) 1 day ago

Also available in: Atom PDF