#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 /** * 通用的存储文件句柄对象类型定义 */ 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