Method: File#flock

Defined in:
file.c

#flock(operation) ⇒ Object

:markup: markdown

call-seq:

flock(locking_constant) -> 0 or false

Locks or unlocks file self according to the given ‘locking_constant`, a bitwise OR of the values in the table below.

Not available on all platforms.

Returns ‘false` if `File::LOCK_NB` is specified and the operation would have blocked; otherwise returns `0`.

| Constant | Lock | Effect |—————–|————–|—————————————————————————————————————–| | File::LOCK_EX | Exclusive | Only one process may hold an exclusive lock for self at a time. | | File::LOCK_NB | Non-blocking | No blocking; may be combined with File::LOCK_SH or File::LOCK_EX using the bitwise OR operator \|. | | File::LOCK_SH | Shared | Multiple processes may each hold a shared lock for self at the same time. | | File::LOCK_UN | Unlock | Remove an existing lock held by this process. |

Example:

“‘ruby # Update a counter using an exclusive lock. # Don’t use File::WRONLY because it truncates the file. File.open(‘counter’, File::RDWR | File::CREAT, 0644) do |f|

f.flock(File::LOCK_EX)
value = f.read.to_i + 1
f.rewind
f.write("#{value}\n")
f.flush
f.truncate(f.pos)

end

# Read the counter using a shared lock. File.open(‘counter’, ‘r’) do |f|

f.flock(File::LOCK_SH)
f.read

end “‘



5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
# File 'file.c', line 5377

static VALUE
rb_file_flock(VALUE obj, VALUE operation)
{
    rb_io_t *fptr;
    int op[2], op1;
    struct timeval time;

    op[1] = op1 = NUM2INT(operation);
    GetOpenFile(obj, fptr);
    op[0] = fptr->fd;

    if (fptr->mode & FMODE_WRITABLE) {
        rb_io_flush_raw(obj, 0);
    }
    while ((int)rb_io_blocking_region(fptr, rb_thread_flock, op) < 0) {
        int e = errno;
        switch (e) {
          case EAGAIN:
          case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
          case EWOULDBLOCK:
#endif
            if (op1 & LOCK_NB) return Qfalse;

            time.tv_sec = 0;
            time.tv_usec = 100 * 1000;	/* 0.1 sec */
            rb_thread_wait_for(time);
            rb_io_check_closed(fptr);
            continue;

          case EINTR:
#if defined(ERESTART)
          case ERESTART:
#endif
            break;

          default:
            rb_syserr_fail_path(e, fptr->pathv);
        }
    }
    return INT2FIX(0);
}