mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 13:25:45 +02:00
fd: deprecate Resource in favor of NamedPtr
Rewrite Fd using a much simpler named resource template class with a more straightforward derivation strategy. Behavior change: we no longer throw an exception while calling get_fd() on a closed Fd. This does not seem to bother any current callers except for the tests. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
ab5316a3da
commit
c80af1cb4f
@ -1,7 +1,7 @@
|
|||||||
#ifndef CRUCIBLE_FD_H
|
#ifndef CRUCIBLE_FD_H
|
||||||
#define CRUCIBLE_FD_H
|
#define CRUCIBLE_FD_H
|
||||||
|
|
||||||
#include "crucible/resource.h"
|
#include "crucible/namedptr.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -34,29 +34,28 @@ namespace crucible {
|
|||||||
IOHandle(IOHandle &&) = delete;
|
IOHandle(IOHandle &&) = delete;
|
||||||
IOHandle& operator=(IOHandle &&) = delete;
|
IOHandle& operator=(IOHandle &&) = delete;
|
||||||
IOHandle& operator=(const IOHandle &) = delete;
|
IOHandle& operator=(const IOHandle &) = delete;
|
||||||
protected:
|
|
||||||
int m_fd;
|
int m_fd;
|
||||||
IOHandle& operator=(int that) { m_fd = that; return *this; }
|
|
||||||
public:
|
public:
|
||||||
virtual ~IOHandle();
|
virtual ~IOHandle();
|
||||||
IOHandle(int fd);
|
IOHandle(int fd = -1);
|
||||||
IOHandle();
|
int get_fd() const;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
int get_fd() const { return m_fd; }
|
|
||||||
int release_fd();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
class Fd {
|
||||||
struct ResourceTraits<int, IOHandle> {
|
static NamedPtr<IOHandle, int> s_named_ptr;
|
||||||
int get_key(const IOHandle &res) const { return res.get_fd(); }
|
shared_ptr<IOHandle> m_handle;
|
||||||
shared_ptr<IOHandle> make_resource(int fd) const { return make_shared<IOHandle>(fd); }
|
public:
|
||||||
bool is_null_key(const int &key) const { return key < 0; }
|
using resource_type = IOHandle;
|
||||||
int get_null_key() const { return -1; }
|
Fd();
|
||||||
|
Fd(int fd);
|
||||||
|
Fd &operator=(int fd);
|
||||||
|
Fd &operator=(const shared_ptr<IOHandle> &);
|
||||||
|
operator int() const;
|
||||||
|
bool operator!() const;
|
||||||
|
shared_ptr<IOHandle> operator->() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ResourceHandle<int, IOHandle> Fd;
|
|
||||||
|
|
||||||
void set_relative_path(string path);
|
void set_relative_path(string path);
|
||||||
string relative_path();
|
string relative_path();
|
||||||
|
|
||||||
|
56
lib/fd.cc
56
lib/fd.cc
@ -107,12 +107,6 @@ namespace crucible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IOHandle::IOHandle() :
|
|
||||||
m_fd(-1)
|
|
||||||
{
|
|
||||||
CHATTER_TRACE("open fd " << m_fd << " in " << this);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOHandle::IOHandle(int fd) :
|
IOHandle::IOHandle(int fd) :
|
||||||
m_fd(fd)
|
m_fd(fd)
|
||||||
{
|
{
|
||||||
@ -120,12 +114,52 @@ namespace crucible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
IOHandle::release_fd()
|
IOHandle::get_fd() const
|
||||||
{
|
{
|
||||||
CHATTER_TRACE("release fd " << m_fd << " in " << this);
|
return m_fd;
|
||||||
int rv = m_fd;
|
}
|
||||||
m_fd = -1;
|
|
||||||
return rv;
|
NamedPtr<IOHandle, int> Fd::s_named_ptr([](int fd) { return make_shared<IOHandle>(fd); });
|
||||||
|
|
||||||
|
Fd::Fd() :
|
||||||
|
m_handle(s_named_ptr(-1))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Fd::Fd(int fd) :
|
||||||
|
m_handle(s_named_ptr(fd < 0 ? -1 : fd))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Fd &
|
||||||
|
Fd::operator=(int const fd)
|
||||||
|
{
|
||||||
|
m_handle = s_named_ptr(fd < 0 ? -1 : fd);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fd &
|
||||||
|
Fd::operator=(const shared_ptr<IOHandle> &handle)
|
||||||
|
{
|
||||||
|
m_handle = s_named_ptr.insert(handle, handle->get_fd());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fd::operator int() const
|
||||||
|
{
|
||||||
|
return m_handle->get_fd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Fd::operator!() const
|
||||||
|
{
|
||||||
|
return m_handle->get_fd() < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<IOHandle>
|
||||||
|
Fd::operator->() const
|
||||||
|
{
|
||||||
|
return m_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: necessary? useful?
|
// XXX: necessary? useful?
|
||||||
|
36
test/fd.cc
36
test/fd.cc
@ -207,8 +207,8 @@ static void test_assign_int_close()
|
|||||||
assert(j == -1);
|
assert(j == -1);
|
||||||
// Bonus conversion operator tests
|
// Bonus conversion operator tests
|
||||||
assert(fd == -1);
|
assert(fd == -1);
|
||||||
// Chasing a closed ref now triggers an exception
|
// Chasing a closed ref no longer triggers an exception
|
||||||
assert(catch_all([&]() { return fd->get_fd() == -1; }));
|
assert(fd->get_fd() == -1);
|
||||||
}
|
}
|
||||||
assert_is_closed(i, true);
|
assert_is_closed(i, true);
|
||||||
}
|
}
|
||||||
@ -228,8 +228,8 @@ static void test_assign_int_close_2()
|
|||||||
assert(j == -1);
|
assert(j == -1);
|
||||||
// Bonus conversion operator tests
|
// Bonus conversion operator tests
|
||||||
assert(fd == -1);
|
assert(fd == -1);
|
||||||
// Chasing a closed ref now triggers an exception
|
// Chasing a closed ref no longer triggers an exception
|
||||||
assert(catch_all([&]() { return fd->get_fd() == -1; }));
|
assert(fd->get_fd() == -1);
|
||||||
}
|
}
|
||||||
assert_is_closed(i, true);
|
assert_is_closed(i, true);
|
||||||
}
|
}
|
||||||
@ -285,13 +285,23 @@ static void test_shared_close_method()
|
|||||||
|
|
||||||
struct DerivedFdResource : public Fd::resource_type {
|
struct DerivedFdResource : public Fd::resource_type {
|
||||||
string m_name;
|
string m_name;
|
||||||
DerivedFdResource(string name) : m_name(name) {
|
DerivedFdResource(string name) : Fd::resource_type(open(name.c_str(), O_RDONLY)), m_name(name) {
|
||||||
Fd::resource_type::operator=(open(name.c_str(), O_RDONLY));
|
|
||||||
assert_is_closed(this->get_fd(), false);
|
assert_is_closed(this->get_fd(), false);
|
||||||
}
|
}
|
||||||
const string &name() const { return m_name; }
|
const string &name() const { return m_name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
shared_ptr<T>
|
||||||
|
cast(const Fd &fd)
|
||||||
|
{
|
||||||
|
auto dp = dynamic_pointer_cast<T>(fd.operator->());
|
||||||
|
if (!dp) {
|
||||||
|
throw bad_cast();
|
||||||
|
}
|
||||||
|
return dp;
|
||||||
|
}
|
||||||
|
|
||||||
struct DerivedFd : public Fd {
|
struct DerivedFd : public Fd {
|
||||||
using resource_type = DerivedFdResource;
|
using resource_type = DerivedFdResource;
|
||||||
DerivedFd(string name) {
|
DerivedFd(string name) {
|
||||||
@ -299,7 +309,7 @@ struct DerivedFd : public Fd {
|
|||||||
Fd::operator=(static_pointer_cast<Fd::resource_type>(ptr));
|
Fd::operator=(static_pointer_cast<Fd::resource_type>(ptr));
|
||||||
}
|
}
|
||||||
shared_ptr<DerivedFdResource> operator->() const {
|
shared_ptr<DerivedFdResource> operator->() const {
|
||||||
shared_ptr<DerivedFdResource> rv = cast<DerivedFdResource>();
|
shared_ptr<DerivedFdResource> rv = cast<DerivedFdResource>(*this);
|
||||||
THROW_CHECK1(out_of_range, rv, rv);
|
THROW_CHECK1(out_of_range, rv, rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -328,12 +338,12 @@ static void test_derived_cast()
|
|||||||
Fd fd2(fd);
|
Fd fd2(fd);
|
||||||
Fd fd3 = open("fd.cc", O_RDONLY);
|
Fd fd3 = open("fd.cc", O_RDONLY);
|
||||||
assert(fd->name() == "fd.cc");
|
assert(fd->name() == "fd.cc");
|
||||||
assert(fd.cast<Fd::resource_type>());
|
assert(cast<Fd::resource_type>(fd));
|
||||||
assert(fd.cast<DerivedFd::resource_type>());
|
assert(cast<DerivedFd::resource_type>(fd));
|
||||||
assert(fd2.cast<Fd::resource_type>());
|
assert(cast<Fd::resource_type>(fd2));
|
||||||
assert(fd2.cast<DerivedFd::resource_type>());
|
assert(cast<DerivedFd::resource_type>(fd2));
|
||||||
assert(fd3.cast<Fd::resource_type>());
|
assert(cast<Fd::resource_type>(fd3));
|
||||||
assert(catch_all([&](){ assert(!fd3.cast<DerivedFd::resource_type>()); } ));
|
assert(catch_all([&](){ assert(!cast<DerivedFd::resource_type>(fd3)); } ));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_derived_map()
|
static void test_derived_map()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user