#ifndef	ACL_FHANDLE_INCLUDE_H
#define	ACL_FHANDLE_INCLUDE_H

#ifdef	__cplusplus
extern "C" {
#endif

#include "acl_define.h"
#include "acl_vstream.h"
#include "acl_vstring.h"
#include "acl_ring.h"
#include "../thread/acl_thread.h"
#include <time.h>

/**
 * ͨõĴ洢ļͶ
 */

typedef struct ACL_FHANDLE	ACL_FHANDLE;

struct ACL_FHANDLE {
	ACL_VSTREAM *fp;			/**< 洢ļ */
	acl_int64 fsize;			/**< 洢ļС */
	int   nrefer;				/**< ô洢õļֵ */
	acl_pthread_mutex_t mutex;		/**< ߳ */
#if defined(_WIN32) || defined(_WIN64)
	unsigned long tid;			/**< 򿪸ô洢̺߳ */
	unsigned long lock_mutex_tid;		/**< ̺߳߳ */
#else
	acl_pthread_t tid;			/**< 򿪸ô洢̺߳ */
	acl_pthread_t lock_mutex_tid;		/**< ̺߳߳ */
#endif
	unsigned int oflags;			/**< ʱı־λ */
#define	ACL_FHANDLE_O_FLOCK	(1 << 0)	/**< ʹļ */
#define	ACL_FHANDLE_O_MLOCK	(1 << 1)	/**< ʹ߳ */
#define	ACL_FHANDLE_O_MKDIR	(1 << 2)	/**< ǷԶ鲢ڵĿ¼ */
#define	ACL_FHANDLE_O_NOATIME	(1 << 3)	/**< ļʱ O_NOATIME ־λ */
#define	ACL_FHANDLE_O_DIRECT	(1 << 4)	/**< ļʱ O_DIRECT ־λ */
#define	ACL_FHANDLE_O_SYNC	(1 << 5)	/**< ļʱ O_SYNC ־λ */
#define	ACL_FHANDLE_O_EXCL	(1 << 6)	/**< ļʱǷԶ */

	unsigned int status;			/**< ô洢ļ״̬ */
#define	ACL_FHANDLE_S_FLOCK_ON	(1 << 0)	/**< ô洢Ѿļ */
#define	ACL_FHANDLE_S_MUTEX_ON	(1 << 1)	/**< ô洢Ѿ߳ */

	time_t  when_free;			/**< ӳٹرջдʱ */
	ACL_RING ring;				/**< ݽ */
	size_t size;				/**<  ACL_FHANDLE ʵʴС >= sizeof(ACL_FHANDLE) */
	void (*on_close)(ACL_FHANDLE*);		/**< ļرʱĻصΪ */
};

#define	ACL_FHANDLE_PATH(x)	(ACL_VSTREAM_PATH((x)->fp))

/**
 * ʼļúڳгʼʱֻܱһ
 * @param cache_size {int} ڲļ
 * @param debug_section {int} Լ
 * @param flags {unsigned int}
 */
void acl_fhandle_init(int cache_size, int debug_section, unsigned int flags);
#define	ACL_FHANDLE_F_LOCK	(1 << 0)

/**
 * ˳ʱҪô˺ͷϵͳԴ
 */
void acl_fhandle_end(void);

/**
 * һļ
 * @param size {size_t} ṹ FS_HANDDLE ҪĿռС
 * @param oflags {unsigned int} ļʱı־λ, ACL_FHANDLE_O_XXX
 * @param file_path {const char*} ļ(·)
 * @param on_open {int (*)(ACL_FHANDLE*, void*)} Ϊգ
 *  ļɹ򿪺ô˺
 * @param open_arg {void *} on_open Ļص֮һ
 * @param on_close {void (*)(ACL_FHANDLE*)} Ϊգ
 *  ļֱرʱô˺
 */
ACL_FHANDLE *acl_fhandle_open(size_t size, unsigned int oflags,
	const char *file_path,
	int (*on_open)(ACL_FHANDLE*, void*), void *open_arg,
	void (*on_close)(ACL_FHANDLE*));

/**
 * رһļ
 * @param fs {ACL_FHANDLE*}
 * @param delay_timeout {int}  > 0, ӳٸʱر,
 *  üΪ 0 ر
 */
void acl_fhandle_close(ACL_FHANDLE *fs, int delay_timeout);

/**
 * һļ(ȼ߳ļ)
 * @param fs {ACL_FHANDLE*}
 */
void acl_fhandle_lock(ACL_FHANDLE *fs);

/**
 * һļ(Ƚļٽ߳)
 * @param fs {ACL_FHANDLE*}
 */
void acl_fhandle_unlock(ACL_FHANDLE *fs);

#ifdef	__cplusplus
}
#endif

#endif
