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