#ifndef	ACL_IOSTUFF_INCLUDE_H
#define	ACL_IOSTUFF_INCLUDE_H

#ifdef	__cplusplus
extern "C" {
#endif

#include "acl_define.h"
#include "acl_vstream.h"

#define ACL_CLOSE_ON_EXEC   1  /**< ־λ,  exec Զرմ򿪵 */
#define ACL_PASS_ON_EXEC    0

#define ACL_BLOCKING        0  /**< д־λ */
#define ACL_NON_BLOCKING    1  /**< д־λ */

/**
 * ׽ӿΪ
 * @param fd {ACL_SOCKET} SOCKET ׽
 * @param on {int} Ƿø׽Ϊ, ACL_BLOCKING  ACL_NON_BLOCKING
 * @return {int} >= 0: ɹ, ֵ > 0 ʾ֮ǰı־λ; -1: ʧ
 */
ACL_API int acl_non_blocking(ACL_SOCKET fd, int on);

/**
 * жװǷΪģʽ
 * @param fd {ACL_SOCKET}  SOCKET ׽
 * @return {int} -1 ʾƽ̨֧֣1 ʾ׽Ϊģʽ
 *  0 ʾ׽Ϊģʽ
 */
ACL_API int acl_is_blocking(ACL_SOCKET fd);

/**
 * дȴֱ׽ֿдʱ
 * @param fd {ACL_SOCKET} 
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} 0: д; -1: ʧܻʱ
 */
ACL_API int acl_write_wait(ACL_SOCKET fd, int timeout);

/**
 * дȴֱ׽ֿдʱ
 * @param fd {ACL_SOCKET} 
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} 0: д; -1: ʧܻʱ
 */
ACL_API int acl_write_wait_ms(ACL_SOCKET fd, int timeout);

/**
 * ȴֱ׽ݿɶʱ
 * @param fd {ACL_SOCKET} 
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} 0: ݿɶֳ; -1: ʧܻʱ
 */
ACL_API int acl_read_wait(ACL_SOCKET fd, int timeout);

/**
 * ȴֱ׽ݿɶʱ
 * @param fd {ACL_SOCKET} 
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} 0: ݿɶֳ; -1: ʧܻʱ
 */
ACL_API int acl_read_wait_ms(ACL_SOCKET fd, int timeout);

#if defined(ACL_LINUX) && !defined(MINGW)
/**
 *  epoll ʽĶȴ
 * @param fd {ACL_SOCKET} 
 * @param delay {int} 뼶ȴʱ
 * @return {int} ͬ
 */
ACL_API int acl_read_epoll_wait(ACL_SOCKET fd, int delay);
#endif

#if defined(ACL_UNIX)
/**
 *  poll ʽĶȴ
 * @param fd {ACL_SOCKET} 
 * @param delay {int} 뼶ȴʱ
 * @return {int} ͬ
 */
ACL_API int acl_read_poll_wait(ACL_SOCKET fd, int delay);
#endif

/**
 *  select ʽĶȴ
 * @param fd {ACL_SOCKET} 
 * @param delay {int} 뼶ȴʱ
 * @return {int} ͬ
 */
ACL_API int acl_read_select_wait(ACL_SOCKET fd, int delay);

/**
 * 뼶˯
 * @param delay {unsigned} ֵ
 */
ACL_API void acl_doze(unsigned delay);

/**
* ĳǷɶ
* @param fd {ACL_SOCKET} 
* @return {int} 0: ɶ; -1:  1ɶ
*/
ACL_API int acl_readable(ACL_SOCKET fd);

/**
 * ʱ
 * @param fd {ACL_SOCKET} ׽
 * @param buf {void*} 洢Ϊ
 * @param len {unsigned} buf 洢С
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} > 0 ; -1: 
*/
ACL_API int acl_timed_read(ACL_SOCKET fd, void *buf, unsigned len,
	int timeout, void *unused_context);

/**
 * ʱд
 * @param fd {ACL_SOCKET} ׽
 * @param buf {void*} ݴ洢Ϊ
 * @param len {unsigned} ݳȴС
 * @param timeout {int} ʱʱ䣬λΪ룬ֵΣ
 *  > 0  : ʾʱʱ
 *  == 0 : ʾȴ
 *  < 0  : ʱʾֱӸ׽ֿɶΪֹ
 * @return {int} > 0 ɹд; -1: 
 */
ACL_API int acl_timed_write(ACL_SOCKET fd, void *buf, unsigned len,
	int timeout, void *unused_context);

/**
 * ѭдݣֱдꡢʱΪֹ
 * @param fd {ACL_SOCKET} ׽
 * @param buf {void*} ݴ洢Ϊ
 * @param len {unsigned} ݳȴС
 * @param timeout {int} ʱʱ䣬λΪ
 * @return {int} ɹдĳ
 */
ACL_API int acl_write_buf(ACL_SOCKET fd, const char *buf, int len, int timeout);

/**
 * ̽׽ϵͳݳ
 * @param fd {ACL_SOCKET} 
 * @return {int} ϵͳݳ
 */
ACL_API int acl_peekfd(ACL_SOCKET fd);

/**
 * ܵ
 * @param fds {ACL_FILE_HANDLE [2]} 洢
 * @return {int} 0: ok; -1: error
 */
ACL_API int acl_pipe(ACL_FILE_HANDLE fds[2]);

/**
 * رչܵ
 * @param fds {ACL_FILE_HANDLE[2]} ܵ
 * @return {int} 0: ok; -1: error
 */
ACL_API int acl_pipe_close(ACL_FILE_HANDLE fds[2]);

/**
* һܵ
* @param fds {ACL_FILE_HANDLE[2]} 洢ĹܵԵַΪ
* @return 0: ok; -1: error
*/
ACL_API int acl_duplex_pipe(ACL_FILE_HANDLE fds[2]);

#ifdef	ACL_UNIX
/**
 * ļ־λ exec Զر
 * @param fd {int} ļ
 * @param on {int} ACL_CLOSE_ON_EXEC  0
 * @return {int} 0: ok; -1: error
 */
ACL_API int acl_close_on_exec(int fd, int on);

/**
 * ĳļʼر֮д򿪵ļ
 * @param lowfd {int} رֵ
 * @return {int} 0: ok; -1: error
 */
ACL_API int acl_closefrom(int lowfd);

/**
 * 趨ǰ̿Դļֵ
 * @param limit {int} 趨ֵ
 * @return {int} >=0: ok; -1: error
 */
ACL_API int acl_open_limit(int limit);

/**
 * жϸĳļǷ׽
 * @param fd {int} ļ
 * @return {int} != 0: ; 0: 
 */
ACL_API int acl_issock(int fd);
#endif

ACL_API void acl_set_delay_slice(int n);

#if defined(_WIN32) || defined(_WIN64)
typedef int (WINAPI *acl_select_fn)(int, fd_set*, fd_set*,
	fd_set*, const struct timeval*);
# if(_WIN32_WINNT >= 0x0600)
#  define ACL_HAS_POLL
typedef int (WINAPI *acl_poll_fn)(struct pollfd*, unsigned long, int);
ACL_API void acl_set_poll(acl_poll_fn fn);
# endif

#else
#include <poll.h>
# define ACL_HAS_POLL

typedef int (*acl_select_fn)(int, fd_set*, fd_set*, fd_set*, struct timeval*);
typedef int (*acl_poll_fn)(struct pollfd*, nfds_t, int);
ACL_API void acl_set_poll(acl_poll_fn fn);
#endif

ACL_API void acl_set_select(acl_select_fn fn);

#ifdef	__cplusplus
}
#endif

#endif
