Compare commits

...

7 Commits

Author SHA1 Message Date
Avril 130f21f57e
Removed rust version from master
2 years ago
Avril 671fcd3968
Merge branch 'rust': Wrong branch, whoops.
2 years ago
Avril 0d082f5b6f
Added `cow_create_fd(fd, size)`: Create a `cow_t*` over an already existing file descriptor
2 years ago
Avril 6f21491298
typed OO bullshit
3 years ago
Avril 2d4ebc3142
error type
3 years ago
Avril 7b623e0fdf
rust bindings: start
3 years ago
Avril 7e4e3f9867
kill me
3 years ago

2
.gitignore vendored

@ -4,3 +4,5 @@ cow-*
obj/
*~
vgcore.*
target/
!cowslice/*.a

@ -5,7 +5,7 @@ PROJECT=cow
AUTHOR=Avril (Flanchan) <flanchan@cumallover.me>
VERSION_MAJOR=0
VERSION_MINOR=2.0
VERSION_MINOR=3.0
VERSION=$(VERSION_MAJOR).$(VERSION_MINOR)
ifeq ($(PREFIX),)

@ -35,6 +35,13 @@ typedef struct cow_mapped_slice cow_t;
/// Writes to this instance pointer (`cow_ptr()`) are written to the allocated memory.
/// Writes to any cloned instances do not propagate to this instance.
cow_t* cow_create(size_t size);
/// Create a new copy-on-write area of `size` bytes from file `fd`.
/// Writes to this instance pointer (`cow_ptr()`) are written to the allocated memory.
/// Writes to any cloned instances do not propagate to this instance.
///
/// The resulting object does not own `fd`, but does own a duplicate of it.
cow_t* cow_create_fd(int fd, size_t size);
/// Free a cow area. This should be called on all clones before the parent of those clones is freed.
void cow_free(cow_t* restrict cow);
/// Create a clone of this instance. Any writes to the returned pointer will not be propagated to the input one.

@ -21,7 +21,9 @@ struct Cow : public _cow_util::Span<unsigned char> {
struct Fake;
Cow() = delete;
Cow(int fd, size_t size);
explicit Cow(size_t size);
Cow(Cow&& m);
virtual ~Cow();

@ -3,10 +3,68 @@
#include <cow.hpp>
#include <utility>
XXX: Fuck this. Rewrite to use composition. Inheritance is a comlpete joke.
template<typename T>
struct TypedCow : public _cow_util::Span<T> {
struct Fake;
template<typename... Args>
inline TypedCow(size_t sz, Args&&... args) : real(Cow(sz * sizeof(T))) { init_copy( T(std::forward<Args>(args)...) ); }
inline TypedCow(size_t sz, const T& copy) : real(Cow(sz * sizeof(T))) { init_copy(copy); }
inline TypedCow(size_t sz) : TypedCow(sz, T()){}
inline virtual ~TypedCow() { uninit(); }
inline virtual Fake clone() const { return Fake(*this); }
inline virtual cow_t* raw() const { return real.raw(); }
inline size_t size() const { return real.size() / sizeof(T); }
protected:
//inline explicit TypedCow(const TypedCow<T>& unsafeCopy) : real(Cow(unsafeCopy.real)){}
inline virtual void* area() override { return reinterpret_cast<void*>( real.ptr() ); }
inline virtual const void* area() const override { return reinterpret_cast<const void*>( real.ptr() ); }
inline void init_copy(const T& copy_from) {
T* ptr = this->ptr();
for(size_t i=0;i<size();i++)
new ((void*)(ptr+i)) T(copy_from);
}
// UNSAFE: Explicitly calls destructors of each element in this instance.
inline void uninit() {
T* ptr = this->ptr();
if(!ptr) return;
for(size_t i=0;i<size();i++)
(ptr+i)->~T();
}
private:
Cow real;
};
template<typename T>
struct TypedCow : private Cow, public _cow_util::Span<T> {
struct TypedCow<T>::Fake : public TypedCow<T> {
//XXX: How THE FUCK do we initialise base's `real` here?????
Fake() = delete;
inline Fake(const Fake& copy) : fake(cow_clone(copy.fake)){}
inline Fake(Fake&& move) : fake(move.fake) { *const_cast<cow_t**>(&move.fake) = nullptr; }
inline Fake(const TypedCow<T>& clone) : fake(cow_clone(clone.raw())){}
inline cow_t* raw() const override { return fake; }
inline Fake clone() const override { return Fake(*this); }
inline ~Fake(){}
inline size_t size() const override { return fake ? cow_size(fake) : 0; }
protected:
inline void* area() override { return fake ? cow_ptr(fake) : nullptr; }
inline const void* area() const override { return fake ? cow_ptr_of(const void, fake) : nullptr; }
private:
cow_t* const fake;
};
#if 0
struct Fake;
friend class Fake;
@ -16,8 +74,8 @@ struct TypedCow : private Cow, public _cow_util::Span<T> {
inline TypedCow(size_t sz) : Cow(sz * sizeof(T)) { init_copy(T()); }
inline TypedCow(size_t sz, const T& copy_from) : TypedCow(sz) { init_copy(copy_from); }
template<typename... Args>
inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward<Args>(args)...) ); }
//template<typename... Args>
//inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward<Args>(args)...) ); }
virtual inline ~TypedCow() { uninit(); }
@ -60,3 +118,4 @@ struct TypedCow<T>::Fake : private Cow::Fake, public _cow_util::Span<T> {
inline const void* area() const override { return Cow::Fake::area(); }
inline void* area() override { return Cow::Fake::area(); }
};
#endif

@ -76,13 +76,13 @@ size_t cow_size(const cow_t* cow)
return cow->size;
}
inline internal cow_t _cow_create_unboxed(size_t size)
inline internal cow_t _cow_create_unboxed(int _fd, size_t size)
{
cow_t ret;
ret.size = size;
if( (ret.poisoned =
((ret.fd = shm_fd(size)) == -1))
((ret.fd = _fd < 0 ? shm_fd(size) : _fd) == -1))
) {
ret.origin = NULL;
return ret;
@ -96,7 +96,14 @@ inline internal cow_t _cow_create_unboxed(size_t size)
}
cow_t* cow_create(size_t size)
{
return box_value(_cow_create_unboxed(size));
return box_value(_cow_create_unboxed(-1, size));
}
cow_t* cow_create_fd(int fd, size_t size)
{
fd = dup(fd);
if(__builtin_expect(fd < 0, false)) return NULL;
return box_value(_cow_create_unboxed(fd, size));
}
inline internal void _cow_free_unboxed(const cow_t* cow)

@ -15,6 +15,7 @@ struct Cow::_inner {
~_inner();
_inner(size_t sz);
_inner(int fd, size_t sz);
_inner(cow_t* ptr);
_inner(const _inner& copy) = delete;
@ -27,10 +28,12 @@ Cow::_inner::~_inner() {
_cow_free_unboxed(ptr());
cow.poisoned=true;
}
Cow::_inner::_inner(size_t sz) : cow(_cow_create_unboxed(sz)){
Cow::_inner::_inner(int fd, size_t sz) : cow(_cow_create_unboxed(fd, sz)){
if(UNLIKELY(cow.poisoned)) throw CowException(cow_err());
}
Cow::_inner::_inner(size_t sz) : _inner(-1, sz) {}
Cow::_inner::_inner(cow_t* ptr) : cow(*ptr)
{
free(ptr);
@ -38,6 +41,7 @@ Cow::_inner::_inner(cow_t* ptr) : cow(*ptr)
}
Cow::Cow(size_t size) : super(std::make_shared<_inner>(size)){}
Cow::Cow(int fd, size_t size) : super(std::make_shared<_inner>(fd, size)){}
Cow::Cow(cow_t* raw) : super(std::make_shared<_inner>(raw)){}
Cow::Cow(Cow&& m) : super(std::move(*const_cast<std::shared_ptr<_inner>*>(&m.super))){}

@ -44,7 +44,7 @@ _Static_assert
(offsetof(cow_t, size) == sizeof(void*), "`cow_t.size` should have an offset equal to `sizeof(void*)` or cow_size_unsafe() becomes UB.");
#endif
cow_t _cow_create_unboxed(size_t size) internal;
cow_t _cow_create_unboxed(int rfd, size_t size) internal;
void _cow_free_unboxed(const cow_t* cow) internal;
#ifdef __cplusplus

Loading…
Cancel
Save