CernVM-FS  2.13.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:
30  FdTable(unsigned max_open_fds, const HandleT &invalid_handle)
31  : invalid_handle_(invalid_handle)
32  , fd_pivot_(0)
33  , fd_index_(max_open_fds)
34  , open_fds_(max_open_fds, FdWrapper(invalid_handle_, 0)) {
35  assert(max_open_fds > 0);
36  for (unsigned i = 0; i < max_open_fds; ++i) {
37  fd_index_[i] = i;
38  open_fds_[i].index = i;
39  }
40  }
41 
45  void AssignFrom(const FdTable<HandleT> &other) {
47  fd_pivot_ = other.fd_pivot_;
48  fd_index_.resize(other.fd_index_.size());
49  open_fds_.resize(other.open_fds_.size(), FdWrapper(invalid_handle_, 0));
50  for (unsigned i = 0; i < fd_index_.size(); ++i) {
51  fd_index_[i] = other.fd_index_[i];
52  open_fds_[i] = other.open_fds_[i];
53  }
54  }
55 
60  FdTable<HandleT> *result = new FdTable<HandleT>(open_fds_.size(),
62  result->fd_pivot_ = fd_pivot_;
63  for (unsigned i = 0; i < fd_index_.size(); ++i) {
64  result->fd_index_[i] = fd_index_[i];
65  result->open_fds_[i] = open_fds_[i];
66  }
67  return result;
68  }
69 
70 
75  int OpenFd(const HandleT &handle) {
76  if (handle == invalid_handle_)
77  return -EINVAL;
78  if (fd_pivot_ >= fd_index_.size())
79  return -ENFILE;
80 
81  size_t next_fd = fd_index_[fd_pivot_];
82  assert(next_fd < open_fds_.size());
83  assert(open_fds_[next_fd].handle == invalid_handle_);
84  open_fds_[next_fd] = FdWrapper(handle, fd_pivot_);
85  ++fd_pivot_;
86  return next_fd;
87  }
88 
92  HandleT GetHandle(int fd) {
93  return IsValid(fd) ? open_fds_[fd].handle : invalid_handle_;
94  }
95 
96 
101  int CloseFd(int fd) {
102  if (!IsValid(fd))
103  return -EBADF;
104 
105  unsigned index = open_fds_[fd].index;
106  assert(index < fd_index_.size());
107  assert(fd_pivot_ <= fd_index_.size());
108  assert(fd_pivot_ > 0);
109  open_fds_[fd].handle = invalid_handle_;
110  --fd_pivot_;
111  if (index < fd_pivot_) {
112  unsigned other = fd_index_[fd_pivot_];
113  assert(other < open_fds_.size());
114  assert(open_fds_[other].handle != invalid_handle_);
115  open_fds_[other].index = index;
116  fd_index_[index] = other;
117  fd_index_[fd_pivot_] = fd;
118  }
119  return 0;
120  }
121 
122  unsigned GetMaxFds() const { return fd_index_.size(); }
123 
124  private:
125  struct FdWrapper {
126  FdWrapper(HandleT h, unsigned i) : handle(h), index(i) { }
127 
128  HandleT handle;
132  unsigned index;
133  };
134 
135 
136  inline bool IsValid(int fd) {
137  if ((fd < 0) || (static_cast<unsigned>(fd) >= open_fds_.size()))
138  return false;
139  return open_fds_[fd].handle != invalid_handle_;
140  }
141 
149  unsigned fd_pivot_;
155  std::vector<unsigned> fd_index_;
161  std::vector<FdWrapper> open_fds_;
162 }; // class FdTable
163 
164 #endif // CVMFS_FD_TABLE_H_
bool IsValid(int fd)
Definition: fd_table.h:136
void AssignFrom(const FdTable< HandleT > &other)
Definition: fd_table.h:45
unsigned GetMaxFds() const
Definition: fd_table.h:122
FdTable(unsigned max_open_fds, const HandleT &invalid_handle)
Definition: fd_table.h:30
unsigned fd_pivot_
Definition: fd_table.h:149
assert((mem||(size==0))&&"Out Of Memory")
int CloseFd(int fd)
Definition: fd_table.h:101
std::vector< unsigned > fd_index_
Definition: fd_table.h:155
FdTable< HandleT > * Clone()
Definition: fd_table.h:59
unsigned index
Definition: fd_table.h:132
std::vector< FdWrapper > open_fds_
Definition: fd_table.h:161
FdWrapper(HandleT h, unsigned i)
Definition: fd_table.h:126
HandleT invalid_handle_
Definition: fd_table.h:145
int OpenFd(const HandleT &handle)
Definition: fd_table.h:75
HandleT GetHandle(int fd)
Definition: fd_table.h:92