Skip to content

Commit

Permalink
fix: fixed several errors that could lead to unexpected results or Ar…
Browse files Browse the repository at this point in the history
…gon crashing under certain circumstances when using Bytes objects
  • Loading branch information
jacopodl committed Dec 9, 2023
1 parent b10ab9c commit 8c2855b
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 318 deletions.
82 changes: 67 additions & 15 deletions argon/vm/datatype/bufview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,73 @@ void SharedBufferRelease(SharedBuffer *shared) {
}

bool ViewEnlargeNew(BufferView *view, ArSize count) {
SharedBuffer *old = view->shared;
SharedBuffer *tmp;

if ((tmp = SharedBufferNew(view->length + count)) == nullptr)
return false;

// Acquire WriteLock on new SharedBuffer
tmp->rwlock.lock();

MemoryCopy(tmp->buffer, view->buffer, view->length);
view->buffer = tmp->buffer;

SharedBufferRelease(view->shared);
view->shared = tmp;
view->buffer = tmp->buffer;

// Release WriteLock on SharedBuffer
old->rwlock.unlock();

SharedBufferRelease(old);

return true;
}

bool argon::vm::datatype::BufferViewAppendData(BufferView *view, const BufferView *other) {
std::unique_lock view_lock(view->lock);

view->shared->rwlock.lock();

if (view != other)
view->shared->rwlock.lock_shared();

if (!BufferViewEnlarge(view, other->length)) {
view->shared->rwlock.unlock();

if (view != other)
view->shared->rwlock.unlock_shared();

return false;
}

memory::MemoryCopy(view->buffer + view->length, other->buffer, other->length);

view->length += other->length;

if (view != other)
view->shared->rwlock.unlock_shared();

view->shared->rwlock.unlock();

return true;
}

bool argon::vm::datatype::BufferViewAppendData(BufferView *view, const unsigned char *buffer, ArSize length) {
std::unique_lock view_lock(view->lock);

view->shared->rwlock.lock();

if (!BufferViewEnlarge(view, length)) {
view->shared->rwlock.unlock();

return false;
}

memory::MemoryCopy(view->buffer + view->length, buffer, length);

view->length += length;

view->shared->rwlock.unlock();

return true;
}
Expand Down Expand Up @@ -94,6 +151,8 @@ bool argon::vm::datatype::BufferViewHoldBuffer(BufferView *view, unsigned char *
view->shared->buffer = buffer;
view->shared->capacity = cap;

new(&view->lock)std::mutex();

view->buffer = buffer;
view->length = len;

Expand All @@ -104,33 +163,26 @@ bool argon::vm::datatype::BufferViewInit(BufferView *view, ArSize capacity) {
if ((view->shared = SharedBufferNew(capacity)) == nullptr)
return false;

new(&view->lock)std::mutex();
view->buffer = view->shared->buffer;
view->length = 0;

return true;
}

bool argon::vm::datatype::BufferViewInit(BufferView *view, unsigned char *buffer, ArSize length, ArSize capacity) {
if ((view->shared = SharedBufferNew(0)) == nullptr)
return false;

view->shared->buffer = buffer;
view->shared->capacity = capacity;

view->buffer = buffer;
view->length = length;

return true;
}

void argon::vm::datatype::BufferViewDetach(BufferView *view) {
SharedBufferRelease(view->shared);

view->lock.~mutex();
view->buffer = nullptr;
view->length = 0;
}

void argon::vm::datatype::BufferViewInit(BufferView *dst, BufferView *src, ArSize start, ArSize length) {
src->shared->Acquire();

new(&dst->lock)std::mutex();

dst->shared = src->shared;
dst->buffer = src->buffer + start;
dst->length = length;
Expand Down
31 changes: 11 additions & 20 deletions argon/vm/datatype/bufview.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define ARGON_VM_DATATYPE_BUFVIEW_H_

#include <atomic>
#include <shared_mutex>

#include <argon/vm/sync/rsm.h>

Expand All @@ -20,7 +21,7 @@ namespace argon::vm::datatype {
unsigned char *buffer;
ArSize capacity;

bool IsWritable() const {
[[nodiscard]] bool IsWritable() const {
return this->counter == 1;
}

Expand All @@ -29,42 +30,32 @@ namespace argon::vm::datatype {
}

void Acquire() {
// It is used to verify that no one has started writing operations!
std::shared_lock _(this->rwlock);

this->counter++;
}
};

struct BufferView {
std::mutex lock;

SharedBuffer *shared;

unsigned char *buffer;
ArSize length;
};

unsigned char *ReadableBufferLock() {
this->shared->rwlock.lock_shared();
return this->buffer;
}

unsigned char *WritableBufferLock() {
this->shared->rwlock.lock();
return this->buffer;
}

void ReadableRelease() {
this->shared->rwlock.unlock_shared();
}
bool BufferViewAppendData(BufferView *view, const BufferView *other);

void WritableRelease() {
this->shared->rwlock.unlock();
}
};
bool BufferViewAppendData(BufferView *view, const unsigned char *buffer, ArSize length);

bool BufferViewEnlarge(BufferView *view, ArSize count);

bool BufferViewHoldBuffer(BufferView *view, unsigned char *buffer, ArSize len, ArSize cap);

bool BufferViewInit(BufferView *view, ArSize capacity);

bool BufferViewInit(BufferView *view, unsigned char *buffer, ArSize length, ArSize capacity);

void BufferViewDetach(BufferView *view);

void BufferViewInit(BufferView *dst, BufferView *src, ArSize start, ArSize length);
Expand Down
Loading

0 comments on commit 8c2855b

Please sign in to comment.