CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fd_table.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_FD_TABLE_H_
6 #define CVMFS_FD_TABLE_H_
7 
8 #include <errno.h>
9 #include <inttypes.h>
10 #include <stdint.h>
11 
12 #include <cassert>
13 #include <vector>
14 
15 #include "util/single_copy.h"
16 
27 template<class HandleT>
29  public:
31  unsigned max_open_fds,
32  const HandleT &invalid_handle)
33  : invalid_handle_(invalid_handle)
34  , fd_pivot_(0)
35  , fd_index_(max_open_fds)
36  , open_fds_(max_open_fds, FdWrapper(invalid_handle_, 0))
37  {
38  assert(max_open_fds > 0);
39  for (unsigned i = 0; i < max_open_fds; ++i) {
40  fd_index_[i] = i;
41  open_fds_[i].index = i;
42  }
43  }
44 
48  void AssignFrom(const FdTable<HandleT> &other) {
50  fd_pivot_ = other.fd_pivot_;
51  fd_index_.resize(other.fd_index_.size());
52  open_fds_.resize(other.open_fds_.size(), FdWrapper(invalid_handle_, 0));
53  for (unsigned i = 0; i < fd_index_.size(); ++i) {
54  fd_index_[i] = other.fd_index_[i];
55  open_fds_[i] = other.open_fds_[i];
56  }
57  }
58 
63  FdTable<HandleT> *result =
65  result->fd_pivot_ = fd_pivot_;
66  for (unsigned i = 0; i < fd_index_.size(); ++i) {
67  result->fd_index_[i] = fd_index_[i];
68  result->open_fds_[i] = open_fds_[i];
69  }
70  return result;
71  }
72 
73 
78  int OpenFd(const HandleT &handle) {
79  if (handle == invalid_handle_)
80  return -EINVAL;
81  if (fd_pivot_ >= fd_index_.size())
82  return -ENFILE;
83 
84  size_t next_fd = fd_index_[fd_pivot_];
85  assert(next_fd < open_fds_.size());
86  assert(open_fds_[next_fd].handle == invalid_handle_);
87  open_fds_[next_fd] = FdWrapper(handle, fd_pivot_);
88  ++fd_pivot_;
89  return next_fd;
90  }
91 
95  HandleT GetHandle(int fd) {
96  return IsValid(fd) ? open_fds_[fd].handle : invalid_handle_;
97  }
98 
99 
104  int CloseFd(int fd) {
105  if (!IsValid(fd))
106  return -EBADF;
107 
108  unsigned index = open_fds_[fd].index;
109  assert(index < fd_index_.size());
110  assert(fd_pivot_ <= fd_index_.size());
111  assert(fd_pivot_ > 0);
112  open_fds_[fd].handle = invalid_handle_;
113  --fd_pivot_;
114  if (index < fd_pivot_) {
115  unsigned other = fd_index_[fd_pivot_];
116  assert(other < open_fds_.size());
117  assert(open_fds_[other].handle != invalid_handle_);
118  open_fds_[other].index = index;
119  fd_index_[index] = other;
120  fd_index_[fd_pivot_] = fd;
121  }
122  return 0;
123  }
124 
125  unsigned GetMaxFds() const { return fd_index_.size(); }
126 
127  private:
128  struct FdWrapper {
129  FdWrapper(HandleT h, unsigned i) : handle(h), index(i) { }
130 
131  HandleT handle;
135  unsigned index;
136  };
137 
138 
139  inline bool IsValid(int fd) {
140  if ((fd < 0) || (static_cast<unsigned>(fd) >= open_fds_.size()))
141  return false;
142  return open_fds_[fd].handle != invalid_handle_;
143  }
144 
152  unsigned fd_pivot_;
158  std::vector<unsigned> fd_index_;
164  std::vector<FdWrapper> open_fds_;
165 }; // class FdTable
166 
167 #endif // CVMFS_FD_TABLE_H_
bool IsValid(int fd)
Definition: fd_table.h:139
void AssignFrom(const FdTable< HandleT > &other)
Definition: fd_table.h:48
unsigned GetMaxFds() const
Definition: fd_table.h:125
FdTable(unsigned max_open_fds, const HandleT &invalid_handle)
Definition: fd_table.h:30
unsigned fd_pivot_
Definition: fd_table.h:152
assert((mem||(size==0))&&"Out Of Memory")
int CloseFd(int fd)
Definition: fd_table.h:104
std::vector< unsigned > fd_index_
Definition: fd_table.h:158
FdTable< HandleT > * Clone()
Definition: fd_table.h:62
unsigned index
Definition: fd_table.h:135
std::vector< FdWrapper > open_fds_
Definition: fd_table.h:164
FdWrapper(HandleT h, unsigned i)
Definition: fd_table.h:129
HandleT invalid_handle_
Definition: fd_table.h:148
int OpenFd(const HandleT &handle)
Definition: fd_table.h:78
HandleT GetHandle(int fd)
Definition: fd_table.h:95