O_BINARY
O_BINARY
APR_BUFFERED&&APR_XTHREAD
允许其余成员读取
2)、权限标志位”转换;
同1)理,专有的APR“权限标志位”需要转换为Unix平台通用的“权限标志位”;转换使用函数apr_unix_perms2mode实现,转换根据表4-2的对应关系实现。函数返回的权限最终传递给open函数的标志位。
(3)、调用Unix的本地API打开文件;
(4)、设置apr_file_t变量相关属性值;
APR 文件I/O封装支持非阻塞I/O带超时等待以及缓冲I/O,默认情况下为阻塞的,即BLK_ON。
APR文件的另外一个特殊之处就是支持缓冲特性。由于磁盘读取的速度瓶颈,使得频繁的从磁盘读取文件在一定程度上会影响执行效率,因此为了提高读取效率,APR支持文件的缓存读写,即开辟一块大的缓冲内存区,用以保存实际从磁盘中读取得数据,这样用户每次就不需要读写磁盘,而只要读写内存,通过这种缓冲策略,可以改善一定的性能。是否缓冲可通过“文件打开标志位APR_BUFFERED”设置。一旦设置为缓冲读写,则apr_file_open会在pool中开辟大小为APR_FILE_BUFSIZE(4096)的缓冲区供使用。
创建函数中一个比较重要的就是内存池中apr_file_t类型的清除函数注册。当内存池被销毁的时候,对于所有的apr_file_t类型将调用apr_unix_file_cleanup函数进行清除。与创建类似,清除也包括四方面的工作:
(1)、
(2)、关闭文件描述符filedes,如果文件的打开标志是APR_DELONCLOSE,那么在关闭之后还得将该文件删除;如果文件可能跨进程使用,那么还得销毁互斥锁。
(3)、
4.5 文件读取
4.5.1普通文件读取
文件的读写操作定义在readwrite.c中。函数的原型与标准的接口非常类似:
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
thefile是需要读取的文件的描述结构,而buf是文件读取保存的缓冲区。nbytes则是从文件中需要读取的字节数。Apache中的文件读取在内部分为两种机制:支持读写缓存的和不支持读写缓存的,读写是否需要支持缓存,有apr_file_t内部的buffered成员决定,buffered=1表示内部必须支持缓存,否则不需要使用缓存。
我们首先分析最普通的内部不使用缓存的读写情况,下面是读取的核心代码:
{
apr_ssize_t rv;
apr_size_t bytes_read;
if (*nbytes <= 0) {
*nbytes = 0;
return APR_SUCCESS;
}
{
bytes_read = 0;
if (thefile->ungetchar != -1) {
bytes_read = 1;
*(char *)buf = (char)thefile->ungetchar;
buf = (char *)buf + 1;
(*nbytes)--;
thefile->ungetchar = -1;
if (*nbytes == 0) {
*nbytes = bytes_read;
return APR_SUCCESS;
}
}
do {
rv = read(thefile->filedes, buf, *nbytes); u
} while (rv == -1 && errno == EINTR);
#ifdef USE_WAIT_FOR_IO
if (rv == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
thefile->timeout != 0) {
apr_status_t arv = apr_wait_for_io_or_timeout(thefile, NULL, 1);
if (arv != APR_SUCCESS) { v
*nbytes = bytes_read;
return arv;
}
else {
do {
rv = read(thefile->filedes, buf, *nbytes);
} while (rv == -1 && errno == EINTR);
}
}
#endif
*nbytes = bytes_read;
if (rv == 0) {
thefile->eof_hit = TRUE; w
return APR_EOF;
}