STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
boostfd_file.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * lib/io/boostfd_file.cpp
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2006 Roman Dementiev <[email protected]>
7  * Copyright (C) 2009, 2010 Johannes Singler <[email protected]>
8  * Copyright (C) 2008, 2010 Andreas Beckmann <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
16 
17 #if STXXL_HAVE_BOOSTFD_FILE
18 
19 #include <stxxl/bits/io/iostats.h>
21 
22 #include <boost/filesystem/operations.hpp>
23 #include <boost/filesystem/fstream.hpp>
24 #include <boost/version.hpp>
25 
26 
28 
29 
30 void boostfd_file::serve(const request* req) throw (io_error)
31 {
32  scoped_mutex_lock fd_lock(fd_mutex);
33  assert(req->get_file() == this);
34  offset_type offset = req->get_offset();
35  void* buffer = req->get_buffer();
36  size_type bytes = req->get_size();
37  request::request_type type = req->get_type();
38 
39  try
40  {
41  file_des.seek(offset, BOOST_IOS::beg);
42  }
43  catch (const std::exception& ex)
44  {
46  (io_error,
47  "Error doing seek() in boostfd_request::serve()" <<
48  " offset=" << offset <<
49  " this=" << this <<
50  " buffer=" << buffer <<
51  " bytes=" << bytes <<
52  " type=" << ((type == request::READ) ? "READ" : "WRITE") <<
53  " : " << ex.what());
54  }
55 
56  stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE);
57 
58  if (type == request::READ)
59  {
60  try
61  {
62  std::streamsize rc = file_des.read((char*)buffer, bytes);
63  if (rc != std::streamsize(bytes)) {
64  STXXL_THROW_ERRNO(io_error, " partial read: " << rc << " missing " << (bytes - rc) << " out of " << bytes << " bytes");
65  }
66  }
67  catch (const std::exception& ex)
68  {
70  (io_error,
71  "Error doing read() in boostfd_request::serve()" <<
72  " offset=" << offset <<
73  " this=" << this <<
74  " buffer=" << buffer <<
75  " bytes=" << bytes <<
76  " type=" << ((type == request::READ) ? "READ" : "WRITE") <<
77  " : " << ex.what());
78  }
79  }
80  else
81  {
82  try
83  {
84  std::streamsize rc = file_des.write((char*)buffer, bytes);
85  if (rc != std::streamsize(bytes)) {
86  STXXL_THROW_ERRNO(io_error, " partial write: " << rc << " missing " << (bytes - rc) << " out of " << bytes << " bytes");
87  }
88  }
89  catch (const std::exception& ex)
90  {
92  (io_error,
93  "Error doing write() in boostfd_request::serve()" <<
94  " offset=" << offset <<
95  " this=" << this <<
96  " buffer=" << buffer <<
97  " bytes=" << bytes <<
98  " type=" << ((type == request::READ) ? "READ" : "WRITE") <<
99  " : " << ex.what());
100  }
101  }
102 }
103 
104 const char* boostfd_file::io_type() const
105 {
106  return "boostfd";
107 }
108 
109 boostfd_file::boostfd_file(
110  const std::string& filename,
111  int mode,
112  int queue_id, int allocator_id) : disk_queued_file(queue_id, allocator_id), mode_(mode)
113 {
114  BOOST_IOS::openmode boostfd_mode =
115  (mode & RDWR) ? (BOOST_IOS::out | BOOST_IOS::in) :
116  (mode & WRONLY) ? (BOOST_IOS::out) :
117  (mode & RDONLY) ? (BOOST_IOS::in) :
118  BOOST_IOS::in;
119 
120 #if defined(BOOST_FILESYSTEM_VERSION) && (BOOST_FILESYSTEM_VERSION >= 3)
121  const boost::filesystem::path fspath(filename);
122 #else
123  const boost::filesystem::path fspath(filename,
124  boost::filesystem::native);
125 #endif
126 
127  if (mode & TRUNC)
128  {
129  if (boost::filesystem::exists(fspath))
130  {
131  boost::filesystem::remove(fspath);
132  boost::filesystem::ofstream f(fspath);
133  f.close();
134  assert(boost::filesystem::exists(fspath));
135  }
136  }
137 
138  if (mode & CREAT)
139  {
140  // need to be emulated:
141  if (!boost::filesystem::exists(fspath))
142  {
143  boost::filesystem::ofstream f(fspath);
144  f.close();
145  assert(boost::filesystem::exists(fspath));
146  }
147  }
148 
149  if (mode & DIRECT)
150  {
151  // direct mode not supported in Boost
152  STXXL_MSG("Warning: open()ing " << filename << " without DIRECT mode, boostfd does not support it.");
153  }
154 
155  if (mode & REQUIRE_DIRECT)
156  {
157  // direct mode not supported in Boost
158  STXXL_ERRMSG("Error: open()ing " << filename << " with REQUIRE_DIRECT mode, but boostfd does not support it.");
159  return;
160  }
161 
162  if (mode & SYNC)
163  {
164  // ???
165  }
166 
167 #if (BOOST_VERSION >= 104100)
168  file_des.open(filename, boostfd_mode); // also compiles with earlier Boost versions, but differs semantically
169 #else
170  file_des.open(filename, boostfd_mode, boostfd_mode);
171 #endif
172 }
173 
174 boostfd_file::~boostfd_file()
175 {
176  scoped_mutex_lock fd_lock(fd_mutex);
177  file_des.close();
178 }
179 
180 inline file::offset_type boostfd_file::_size()
181 {
182  return file_des.seek(0, BOOST_IOS::end);
183 }
184 
185 file::offset_type boostfd_file::size()
186 {
187  scoped_mutex_lock fd_lock(fd_mutex);
188  return _size();
189 }
190 
191 void boostfd_file::set_size(offset_type newsize)
192 {
193  scoped_mutex_lock fd_lock(fd_mutex);
194 #ifndef NDEBUG
195  offset_type oldsize = _size();
196 #endif // NDEBUG
197  file_des.seek(newsize, BOOST_IOS::beg);
198  file_des.seek(0, BOOST_IOS::beg); // not important ?
199  assert(_size() >= oldsize);
200 }
201 
202 void boostfd_file::lock()
203 {
204  // FIXME: is there no locking possible/needed/... for boostfd?
205 }
206 
208 
209 #endif // #if STXXL_HAVE_BOOSTFD_FILE
210 // vim: et:ts=4:sw=4
static const int bytes
number of bytes in uint_pair
Definition: uint_types.h:99
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
#define STXXL_ERRMSG(x)
Definition: verbose.h:79
#define STXXL_THROW_ERRNO(exception_type, error_message)
Throws exception_type with &quot;Error in [function] : [error_message] : [errno message]&quot;.
#define STXXL_MSG(x)
Definition: verbose.h:72
#define STXXL_END_NAMESPACE
Definition: namespace.h:17