Project

General

Profile

Feature #4038 ยป io-advise-3.patch

Clarified documentation - runpaint (Run Paint Run Run), 11/10/2010 01:54 AM

View differences:

configure.in
1265 1265
fi
1266 1266
AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot getcwd eaccess\
1267 1267
	      truncate ftruncate chsize times utimes utimensat fcntl lockf lstat\
1268
	      link symlink readlink readdir_r fsync fdatasync fchown\
1268
	      link symlink readlink readdir_r fsync fdatasync fchown posix_fadvise\
1269 1269
	      setitimer setruid seteuid setreuid setresuid setproctitle socketpair\
1270 1270
	      setrgid setegid setregid setresgid issetugid pause lchown lchmod\
1271 1271
	      getpgrp setpgrp getpgid setpgid initgroups getgroups setgroups\
io.c
1

  
1 2
/**********************************************************************
2 3

  
3 4
  io.c -
......
1413 1414
#define rb_io_fdatasync rb_f_notimplement
1414 1415
#endif
1415 1416

  
1417
static VALUE sym_normal,   sym_sequential, sym_random,
1418
             sym_willneed, sym_dontneed, sym_noreuse;
1419
/*
1420
 *  call-seq:
1421
 *     ios.advise(advice, offset=0, len=0) -> nil
1422
 *
1423
 *  Announce an intention to access data from the current file in a
1424
 *  specific pattern. On platforms that do not support the
1425
 *  <em>posix_fadvise(2)</em> system call, this method is a no-op.
1426
 *
1427
 * _advice_ is one of the following symbols:
1428
 *
1429
 *  * :normal - No advice to give; the default assumption for an open file.
1430
 *  * :sequential - The data will be accessed sequentially:
1431
 *     with lower offsets read before higher ones.
1432
 *  * :random - The data will be accessed in random order.
1433
 *  * :willneed - The data will be accessed in the near future.
1434
 *  * :dontneed - The data will not be accessed in the near future.
1435
 *  * :noreuse - The data will only be accessed once.
1436
 *
1437
 * The semantics of a piece of advice are platform-dependent. See
1438
 * <em>man 2 posix_fadvise</em> for details.
1439
 *
1440
 *  "data" means the region of the current file that begins at
1441
 *  _offset_ and extends for _len_ bytes. If _len_ is 0, the region
1442
 *  ends at the last byte of the file. By default, both _offset_ and
1443
 *  _len_ are 0, meaning that the advice applies to the entire file.
1444
 *
1445
 *  If an error occurs, one of the following exceptions will be raised:
1446
 *
1447
 *  * <code>IOError</code> - The <code>IO</code> stream is closed.
1448
 *  * <code>Errno::EBADF</code> - The file descriptor of the current file is
1449
      invalid.
1450
 *  * <code>Errno::EINVAL</code> - An invalid value for _advice_ was given.
1451
 *  * <code>Errno::ESPIPE</code> - The file descriptor of the current
1452
 *  * file refers to a FIFO or pipe. (Linux raises <code>Errno::EINVAL</code>
1453
 *  * in this case).
1454
 *  * <code>TypeError</code> - Either _advice_ was not a Symbol, or one of the
1455
      other arguments was not an <code>Integer</code>.
1456
 *  * <code>RangeError</code> - One of the arguments given was too big/small.
1457
 *
1458
 * This list is not exhaustive; other Errno:: exceptions are also possible.
1459
 */
1460

  
1461
static VALUE
1462
rb_io_advise(int argc, VALUE *argv, VALUE io)
1463
{
1464
  off_t offset, len;
1465
  int advice, rv;
1466
  VALUE initadvice, initoffset, initlen;
1467
  rb_io_t *fptr;
1468

  
1469
  rb_scan_args(argc, argv, "12", &initadvice, &initoffset, &initlen);
1470
  if (TYPE(initadvice) != T_SYMBOL)
1471
      rb_raise(rb_eTypeError, "advice must be a Symbol");
1472

  
1473
  offset = NIL_P(initoffset) ? 0 : NUM2OFFT(initoffset);
1474
  len    = NIL_P(initlen)    ? 0 : NUM2OFFT(initlen);
1475
  advice = 0;
1476

  
1477
  if      (initadvice == sym_normal)     {
1478
#ifdef POSIX_FADV_NORMAL
1479
      advice = POSIX_FADV_NORMAL;
1480
#endif
1481
  }
1482
  else if (initadvice == sym_random)     {
1483
#ifdef POSIX_FADV_RANDOM
1484
      advice = POSIX_FADV_RANDOM;
1485
#endif
1486
  }
1487
  else if (initadvice == sym_sequential) {
1488
#ifdef POSIX_FADV_SEQUENTIAL
1489
      advice = POSIX_FADV_SEQUENTIAL;
1490
#endif
1491
  }
1492
  else if (initadvice == sym_willneed)   {
1493
#ifdef POSIX_FADV_WILLNEED
1494
      advice = POSIX_FADV_WILLNEED;
1495
#endif
1496
  }
1497
  else if (initadvice == sym_dontneed)   {
1498
#ifdef POSIX_FADV_DONTNEED
1499
      advice = POSIX_FADV_DONTNEED;
1500
#endif
1501
  }
1502
  else if (initadvice == sym_noreuse)    {
1503
#ifdef POSIX_FADV_NOREUSE
1504
      advice = POSIX_FADV_NOREUSE;
1505
#endif
1506
  }
1507
  else
1508
      rb_raise(rb_eArgError, "Invalid advice: :%s",
1509
	       RSTRING_PTR(rb_id2str(SYM2ID(initadvice))));
1510

  
1511
#ifdef HAVE_POSIX_FADVISE
1512
  io = GetWriteIO(io);
1513
  GetOpenFile(io, fptr);
1514

  
1515
  if (rv = posix_fadvise(fptr->fd, offset, len, advice))
1516
    /* posix_fadvise(2) doesn't set errno. On success it returns 0; otherwise
1517
       it returns the error code. */
1518
      rb_syserr_fail(rv, RSTRING_PTR(fptr->pathv));
1519
#endif
1520
  return Qnil;
1521
}
1522

  
1416 1523
/*
1417 1524
 *  call-seq:
1418 1525
 *     ios.fileno    -> fixnum
......
10052 10159
    rb_define_method(rb_cIO, "binmode",  rb_io_binmode_m, 0);
10053 10160
    rb_define_method(rb_cIO, "binmode?", rb_io_binmode_p, 0);
10054 10161
    rb_define_method(rb_cIO, "sysseek", rb_io_sysseek, -1);
10162
    rb_define_method(rb_cIO, "advise", rb_io_advise, -1);
10055 10163

  
10056 10164
    rb_define_method(rb_cIO, "ioctl", rb_io_ioctl, -1);
10057 10165
    rb_define_method(rb_cIO, "fcntl", rb_io_fcntl, -1);
......
10220 10328
    sym_textmode = ID2SYM(rb_intern("textmode"));
10221 10329
    sym_binmode = ID2SYM(rb_intern("binmode"));
10222 10330
    sym_autoclose = ID2SYM(rb_intern("autoclose"));
10331
    sym_normal = ID2SYM(rb_intern("normal"));
10332
    sym_sequential = ID2SYM(rb_intern("sequential"));
10333
    sym_random = ID2SYM(rb_intern("random"));
10334
    sym_willneed = ID2SYM(rb_intern("willneed"));
10335
    sym_dontneed = ID2SYM(rb_intern("dontneed"));
10336
    sym_noreuse = ID2SYM(rb_intern("noreuse"));
10223 10337
}