[go: up one dir, main page]

Menu

[8f591a]: / io / ufs_file.h  Maximize  Restore  History

Download this file

218 lines (191 with data), 4.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#ifndef UFSFILEBASE_HEADER
#define UFSFILEBASE_HEADER
/***************************************************************************
* ufs_file.h
* UNIX file system file base
* Sat Aug 24 23:55:13 2002
* Copyright 2002 Roman Dementiev
* dementiev@mpi-sb.mpg.de
****************************************************************************/
#include "iobase.h"
__STXXL_BEGIN_NAMESPACE
//! \addtogroup fileimpl
//! \{
class ufs_request_base;
//! \brief Base for UNIX file system implementations
class ufs_file_base:public file
{
protected:
int file_des; // file descriptor
ufs_file_base (const std::string & filename, int mode, int disk);
private:
ufs_file_base ();
public:
int get_file_des()
{
return file_des;
};
~ufs_file_base();
off_t size ();
void set_size(off_t newsize);
};
//! \brief Base for UNIX file system implementations
class ufs_request_base:public request
{
friend class ufs_file_base;
protected:
// states of request
enum { OP = 0, DONE = 1, READY2DIE = 2 }; // OP - operating, DONE - request served,
// READY2DIE - can be destroyed
ufs_file_base *file;
void *buffer;
off_t offset;
size_t bytes;
request_type type;
state _state;
mutex waiters_mutex;
std::set < onoff_switch * > waiters;
ufs_request_base (
ufs_file_base * f,
void *buf,
off_t off,
size_t b,
request_type t,
completion_handler on_cmpl):
request (on_cmpl),
file (f),
buffer (buf),
offset (off),
bytes (b),
type(t),
_state (OP)
{
#ifdef STXXL_CHECK_BLOCK_ALIGNING
// Linux direct I/O requires filsystem block size alighnment for file offsets,
// memory buffer adresses, and transfer(buffer) size must be multiple
// of the filesystem block size
check_aligning ();
#endif
};/*
void enqueue(request_ptr & req)
{
if (type == READ)
disk_queues::get_instance ()->add_readreq(req,file->get_id());
else
disk_queues::get_instance ()->add_writereq(req,file->get_id());
};*/
bool add_waiter (onoff_switch * sw)
{
waiters_mutex.lock ();
if (poll ()) // request already finished
{
waiters_mutex.unlock ();
return true;
}
waiters.insert (sw);
waiters_mutex.unlock ();
return false;
};
void delete_waiter (onoff_switch * sw)
{
waiters_mutex.lock ();
waiters.erase (sw);
waiters_mutex.unlock ();
};
int nwaiters () // returns number of waiters
{
waiters_mutex.lock ();
int size = waiters.size ();
waiters_mutex.unlock ();
return size;
};
void check_aligning ()
{
if (offset % BLOCK_ALIGN)
STXXL_ERRMSG ("Offset is not aligned: modulo "
<< BLOCK_ALIGN << " = " <<
offset % BLOCK_ALIGN);
if (bytes % BLOCK_ALIGN)
STXXL_ERRMSG ("Size is multiple of " <<
BLOCK_ALIGN << ", = " << bytes % BLOCK_ALIGN);
if (unsigned (buffer) % BLOCK_ALIGN)
STXXL_ERRMSG ("Buffer is not aligned: modulo "
<< BLOCK_ALIGN << " = " <<
unsigned (buffer) % BLOCK_ALIGN << " (" <<
std::hex << buffer << std::dec << ")");
};
public:
virtual ~ufs_request_base ()
{
STXXL_VERBOSE3("ufs_request_base "<< unsigned(this) <<": deletion, cnt: "<<ref_cnt)
_state.wait_for (READY2DIE);
};
void wait ()
{
START_COUNT_WAIT_TIME
#ifdef NO_OVERLAPPING
enqueue();
#endif
_state.wait_for (READY2DIE);
END_COUNT_WAIT_TIME
};
bool poll()
{
#ifdef NO_OVERLAPPING
/*if(_state () < DONE)*/ wait();
#endif
return (_state () >= DONE);
};
const char *io_type ()
{
return "ufs_base";
};
};
ufs_file_base::ufs_file_base (
const std::string & filename,
int mode,
int disk): file (disk), file_des (-1)
{
int fmode = 0;
#ifndef STXXL_DIRECT_IO_OFF
if (mode & DIRECT)
fmode |= O_SYNC | O_RSYNC | O_DSYNC | O_DIRECT;
#endif
if (mode & RDONLY)
fmode |= O_RDONLY;
if (mode & WRONLY)
fmode |= O_WRONLY;
if (mode & RDWR)
fmode |= O_RDWR;
if (mode & CREAT)
fmode |= O_CREAT;
if (mode & TRUNC)
fmode |= O_TRUNC;
stxxl_ifcheck ((file_des =::open (filename.c_str(), fmode,
S_IREAD | S_IWRITE | S_IRGRP | S_IWGRP)));
};
ufs_file_base::~ufs_file_base ()
{
int res =::close (file_des);
// if successful, reset file descriptor
if (res >= 0)
file_des = -1;
else
stxxl_function_error;
};
off_t ufs_file_base::size ()
{
struct stat st;
stxxl_ifcheck (fstat (file_des, &st));
return st.st_size;
};
void ufs_file_base::set_size (off_t newsize)
{
if (newsize > size ())
{
stxxl_ifcheck (::lseek (file_des, newsize - 1,SEEK_SET));
}
};
//! \}
__STXXL_END_NAMESPACE
#endif