io_splice 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -23,6 +23,9 @@ buffer.
23
23
  * Fully-documented library API and
24
24
  {examples}[http://bogomips.org/ruby_io_splice/examples/]
25
25
 
26
+ * Adds helpful IO#pipe_size and IO#pipe_size= accessor methods for
27
+ resizing the pipe buffer in Linux 2.6.35 or later.
28
+
26
29
  == Install
27
30
 
28
31
  Operating system support for the splice(2), tee(2) and vmsplice(2)
@@ -10,6 +10,16 @@
10
10
  #include <sys/uio.h>
11
11
  #include <limits.h>
12
12
  #include <alloca.h>
13
+ #include <sys/utsname.h>
14
+
15
+ #ifndef F_LINUX_SPECIFIC_BASE
16
+ # define F_LINUX_SPECIFIC_BASE 1024
17
+ #endif
18
+
19
+ #ifndef F_GETPIPE_SZ
20
+ # define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
21
+ # define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8)
22
+ #endif
13
23
 
14
24
  #if ! HAVE_RB_IO_T
15
25
  # define rb_io_t OpenFile
@@ -361,9 +371,76 @@ static VALUE my_vmsplice(VALUE self, VALUE fd, VALUE data, VALUE flags)
361
371
  return LONG2NUM(rv);
362
372
  }
363
373
 
374
+ /*
375
+ * call-seq:
376
+ * reader, writer = IO.pipe
377
+ * reader.pipe_size => integer
378
+ *
379
+ * Returns the pipe capacity of the underlying pipe in bytes. The
380
+ * default capacity is 65536 bytes since Linux 2.6.11, and 4096 bytes
381
+ * in previous kernels.
382
+ *
383
+ * Since the pipe is a circular buffer in the same kernel, the size
384
+ * of the reader is exactly the same as the size of the writer.
385
+ *
386
+ * This method is only exposed on Linux 2.6.35 or later.
387
+ */
388
+ static VALUE pipe_size(VALUE self)
389
+ {
390
+ int size = fcntl(my_fileno(self), F_GETPIPE_SZ);
391
+
392
+ if (size < 0)
393
+ rb_sys_fail("fcntl(F_GETPIPE_SZ)");
394
+
395
+ return INT2NUM(size);
396
+ }
397
+
398
+ /*
399
+ * call-seq:
400
+ * reader, writer = IO.pipe
401
+ * reader.pipe_size = integer
402
+ *
403
+ * Sets and returns the pipe capacity of the underlying pipe in bytes.
404
+ *
405
+ * This MUST be a power-of-two, or Errno::EINVAL will be raised.
406
+ * Linux will silently increase this to be equal to the page size
407
+ * (4096 bytes on most architectures) if the specified value is
408
+ * less than the size of a page.
409
+ *
410
+ * For users without CAP_SYS_RESOURCE, this raises Errno::EPERM when
411
+ * attempting to specify a value greater than the value in
412
+ * /proc/sys/fs/pipe-max-size.
413
+ *
414
+ * Since the pipe is a circular buffer in the same kernel, the size
415
+ * of the reader is exactly the same as the size of the writer.
416
+ *
417
+ * Raises Errno::EBUSY if the assigned value is less than
418
+ * the currently filled portion of the pipe.
419
+ *
420
+ * This method is only exposed on Linux 2.6.35 or later.
421
+ */
422
+ static VALUE set_pipe_size(VALUE self, VALUE size)
423
+ {
424
+ int fd = my_fileno(self);
425
+ int bytes = NUM2INT(size);
426
+ int rv = fcntl(fd, F_SETPIPE_SZ, bytes);
427
+
428
+ if (rv < 0) {
429
+ if (errno == ENOMEM) {
430
+ rb_gc();
431
+ rv = fcntl(fd, F_SETPIPE_SZ, bytes);
432
+ }
433
+ if (rv < 0)
434
+ rb_sys_fail("fcntl(F_SETPIPE_SZ)");
435
+ }
436
+
437
+ return size;
438
+ }
439
+
364
440
  void Init_io_splice_ext(void)
365
441
  {
366
442
  VALUE mSplice = rb_define_module_under(rb_cIO, "Splice");
443
+ struct utsname utsname;
367
444
 
368
445
  rb_define_singleton_method(rb_cIO, "splice", my_splice, 6);
369
446
  rb_define_singleton_method(rb_cIO, "tee", my_tee, 4);
@@ -402,19 +479,35 @@ void Init_io_splice_ext(void)
402
479
  */
403
480
  rb_define_const(mSplice, "F_GIFT", UINT2NUM(SPLICE_F_GIFT));
404
481
 
405
- #ifdef F_GETPIPE_SZ
406
- /* :nodoc: */
407
- rb_define_const(mSplice, "F_GETPIPE_SZ", UINT2NUM(F_GETPIPE_SZ));
408
- #endif
409
- #ifdef F_SETPIPE_SZ
410
- /* :nodoc: */
411
- rb_define_const(mSplice, "F_SETPIPE_SZ", UINT2NUM(F_SETPIPE_SZ));
412
- #endif
413
-
414
482
  /*
415
483
  * The maximum size of an atomic write to a pipe
416
484
  * POSIX requires this to be at least 512 bytes.
417
485
  * Under Linux, this is 4096 bytes.
418
486
  */
419
487
  rb_define_const(mSplice, "PIPE_BUF", UINT2NUM(PIPE_BUF));
488
+
489
+ if (uname(&utsname) == -1)
490
+ rb_sys_fail("uname");
491
+
492
+ /* includes 2.6.35-rc[1-6] */
493
+ if (strcmp(utsname.release, "2.6.35") >= 0) {
494
+ rb_define_method(rb_cIO, "pipe_size", pipe_size, 0);
495
+ rb_define_method(rb_cIO, "pipe_size=", set_pipe_size, 1);
496
+
497
+ /*
498
+ * fcntl() command constant used to return the size of a pipe.
499
+ * This constant is only defined when running Linux 2.6.35
500
+ * or later. For convenience, use IO#pipe_size instead.
501
+ */
502
+ rb_define_const(mSplice, "F_GETPIPE_SZ",
503
+ UINT2NUM(F_GETPIPE_SZ));
504
+
505
+ /*
506
+ * fcntl() command constant used to set the size of a pipe.
507
+ * This constant is only defined when running Linux 2.6.35
508
+ * or later. For convenience, use IO#pipe_size= instead.
509
+ */
510
+ rb_define_const(mSplice, "F_SETPIPE_SZ",
511
+ UINT2NUM(F_SETPIPE_SZ));
512
+ }
420
513
  }
data/lib/io/splice.rb CHANGED
@@ -5,8 +5,8 @@ class IO
5
5
 
6
6
  module Splice
7
7
 
8
- # the version of IO::Splice, currently 2.1.0
9
- VERSION = '2.1.0'
8
+ # the version of IO::Splice, currently 2.2.0
9
+ VERSION = '2.2.0'
10
10
 
11
11
  # The maximum default capacity of the pipe in bytes.
12
12
  # Under stock Linux, this is 65536 bytes as of 2.6.11, and 4096 before
@@ -251,7 +251,7 @@ class Test_IO_Splice < Test::Unit::TestCase
251
251
  tmp = []
252
252
  begin
253
253
  sleep 0.005
254
- tmp << rd.readpartial(8192, buf)
254
+ tmp << rd.readpartial(8192)
255
255
  rescue EOFError
256
256
  break
257
257
  end while true
@@ -393,4 +393,19 @@ class Test_IO_Splice < Test::Unit::TestCase
393
393
  assert_equal 'hello world', a.read
394
394
  end
395
395
 
396
+ def test_pipe_size
397
+ r, w = IO.pipe
398
+ assert Integer, r.pipe_size
399
+ assert(r.pipe_size >= 512)
400
+ assert_nothing_raised { w.pipe_size = 8192 }
401
+ assert 8192, r.pipe_size
402
+
403
+ w.write('*' * 4097)
404
+ assert_raises(Errno::EBUSY) { r.pipe_size = 4096 }
405
+
406
+ pipe_max_size = File.read("/proc/sys/fs/pipe-max-size").to_i
407
+ assert_nothing_raised { r.pipe_size = pipe_max_size }
408
+ assert_raises(Errno::EPERM) { r.pipe_size = pipe_max_size * 2 }
409
+ end if IO.method_defined?(:pipe_size)
410
+
396
411
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io_splice
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ hash: 7
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 2
9
+ - 0
10
+ version: 2.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - io_splice hackers
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-06-06 00:00:00 +00:00
18
+ date: 2010-08-02 00:00:00 +00:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
@@ -64,21 +70,27 @@ rdoc_options:
64
70
  require_paths:
65
71
  - lib
66
72
  required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
67
74
  requirements:
68
75
  - - ">="
69
76
  - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
70
80
  version: "0"
71
- version:
72
81
  required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
73
83
  requirements:
74
84
  - - ">="
75
85
  - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
76
89
  version: "0"
77
- version:
78
90
  requirements: []
79
91
 
80
92
  rubyforge_project: qrp
81
- rubygems_version: 1.3.5
93
+ rubygems_version: 1.3.7
82
94
  signing_key:
83
95
  specification_version: 3
84
96
  summary: zero-copy pipe I/O for Linux and Ruby