git » libfilo » master » tree

[master] / libfilo.h

/*
 * libfilo - A File Locking Library
 * Alberto Bertogli (albertogli@telpin.com.ar)
 */


#ifndef _LIBFILO_H
#define _LIBFILO_H

#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>	/* because filo_plockf() uses the same constants as
			 * lockf() */

/* Check if we're using Large File Support - otherwise refuse to build.
 * Otherwise, we would allow applications not using LFS to link with the
 * library (which uses LFS) and that's just begging for problems. There should
 * be a portable way for the C library to do some of this for us, but until I
 * find one, this is the best we can do */
#if (!defined _FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS != 64)
#error "You must compile your application with Large File Support"
#endif

#ifdef __cplusplus
extern "C" {
#endif


/* locking modes */
#define FL_RD_MODE 0
#define FL_WR_MODE 1

/* locking modes for filo_plockf() */
#define _FL_READ	0x00001
#define _FL_WRITE	0x00010
#define _FL_LOCK	0x00100
#define _FL_TLOCK	0x01000
#define _FL_ULOCK	0x10000

#define FL_LOCKR	(_FL_LOCK | _FL_READ)
#define FL_LOCKW	(_FL_LOCK | _FL_WRITE)
#define FL_TLOCKR	(_FL_TLOCK | _FL_READ)
#define FL_TLOCKW	(_FL_TLOCK | _FL_WRITE)
#define FL_ULOCK	(_FL_ULOCK)


/* a single locked range */
struct locked_range {
	off_t start;
	off_t end;
	int mode;
	pthread_t owner;
	struct locked_range *next;
	struct locked_range *prev;
};

/* a range waiting for read or write */
struct waiter_range {
	off_t start;
	off_t end;
	int mode;
	pthread_t owner;
	sem_t sem;
	struct waiter_range *next;
	struct waiter_range *prev;
};

/* a file lock */
typedef struct filo_flock_t {
	struct locked_range *locked;
	struct waiter_range *waiters;
	pthread_mutex_t lock;
} filock_t;


int filo_init(filock_t *fl);
int filo_free(filock_t *fl);
int filo_lock(filock_t *fl, off_t start, off_t len, int mode);
int filo_trylock(filock_t *fl, off_t start, off_t len, int mode);
int filo_unlock(filock_t *fl, off_t start, off_t len);
int filo_plockf(filock_t *fl, int cmd, off_t start, off_t len);

#ifdef __cplusplus
} /* from extern "C" avobe */
#endif

#endif