Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/syscall_file.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * Copyright (C) 2010 Johannes Singler <singler@kit.edu> 00009 * 00010 * Distributed under the Boost Software License, Version 1.0. 00011 * (See accompanying file LICENSE_1_0.txt or copy at 00012 * http://www.boost.org/LICENSE_1_0.txt) 00013 **************************************************************************/ 00014 00015 #include <stxxl/bits/io/syscall_file.h> 00016 #include <stxxl/bits/io/iostats.h> 00017 #include <stxxl/bits/common/error_handling.h> 00018 00019 00020 __STXXL_BEGIN_NAMESPACE 00021 00022 #ifdef BOOST_MSVC 00023 #define lseek _lseeki64 00024 #endif 00025 00026 void syscall_file::serve(const request * req) throw (io_error) 00027 { 00028 scoped_mutex_lock fd_lock(fd_mutex); 00029 assert(req->get_file() == this); 00030 offset_type offset = req->get_offset(); 00031 char * buffer = static_cast<char *>(req->get_buffer()); 00032 size_type bytes = req->get_size(); 00033 request::request_type type = req->get_type(); 00034 00035 stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); 00036 00037 while (bytes > 0) 00038 { 00039 int_type rc; 00040 if ((rc = ::lseek(file_des, offset, SEEK_SET) < 0)) 00041 { 00042 STXXL_THROW2(io_error, 00043 " this=" << this << 00044 " call=::lseek(fd,offset,SEEK_SET)" << 00045 " path=" << filename << 00046 " fd=" << file_des << 00047 " offset=" << offset << 00048 " buffer=" << (void *)buffer << 00049 " bytes=" << bytes << 00050 " type=" << ((type == request::READ) ? "READ" : "WRITE") << 00051 " rc=" << rc); 00052 } 00053 00054 if (type == request::READ) 00055 { 00056 if ((rc = ::read(file_des, buffer, bytes)) <= 0) 00057 { 00058 STXXL_THROW2(io_error, 00059 " this=" << this << 00060 " call=::read(fd,buffer,bytes)" << 00061 " path=" << filename << 00062 " fd=" << file_des << 00063 " offset=" << offset << 00064 " buffer=" << (void *)buffer << 00065 " bytes=" << bytes << 00066 " type=" << "READ" << 00067 " rc=" << rc); 00068 } 00069 bytes -= rc; 00070 offset += rc; 00071 buffer += rc; 00072 00073 if (bytes > 0 && offset == this->_size()) 00074 { 00075 // read request extends past end-of-file 00076 // fill reminder with zeroes 00077 memset(buffer, 0, bytes); 00078 bytes = 0; 00079 } 00080 } 00081 else 00082 { 00083 if ((rc = ::write(file_des, buffer, bytes)) <= 0) 00084 { 00085 STXXL_THROW2(io_error, 00086 " this=" << this << 00087 " call=::write(fd,buffer,bytes)" << 00088 " path=" << filename << 00089 " fd=" << file_des << 00090 " offset=" << offset << 00091 " buffer=" << (void *)buffer << 00092 " bytes=" << bytes << 00093 " type=" << "WRITE" << 00094 " rc=" << rc); 00095 } 00096 bytes -= rc; 00097 offset += rc; 00098 buffer += rc; 00099 } 00100 } 00101 } 00102 00103 const char * syscall_file::io_type() const 00104 { 00105 return "syscall"; 00106 } 00107 00108 __STXXL_END_NAMESPACE 00109 // vim: et:ts=4:sw=4