use std::sync::Arc;
use std::cell::RefCell;
use libc;
use cfile::{Stream, CFileRaw, CFile};
pub struct FileLock(Arc<RefCell<CFileRaw>>);
impl Drop for FileLock {
fn drop(&mut self) {
unsafe { funlockfile(**self.0.borrow()) }
}
}
pub trait FileLockExt {
fn lock(&self) -> FileLock;
fn try_lock(&self) -> Option<FileLock>;
fn unlock(&self);
}
extern "C" {
fn flockfile(file: *mut libc::FILE);
fn ftrylockfile(file: *mut libc::FILE) -> i32;
fn funlockfile(file: *mut libc::FILE);
}
impl<'a> FileLockExt for CFile {
fn lock(&self) -> FileLock {
unsafe { flockfile(self.stream()) }
FileLock((*self).clone())
}
fn try_lock(&self) -> Option<FileLock> {
if unsafe { ftrylockfile(self.stream()) } == 0 {
Some(FileLock((*self).clone()))
} else {
None
}
}
fn unlock(&self) {
unsafe { funlockfile(self.stream()) }
}
}