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);
}
|