mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
don't lock files
that's simpler and enough for now
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
FDT::FD FDT::open(const Path &p, FileOpts opts) {
|
||||
if (auto n = VFSGlobals::root.traverse(p)) {
|
||||
LockGuard l(_mtx);
|
||||
_files.add(_cur_fd++, UniquePtr<File>(new File(n, opts)));
|
||||
return _cur_fd - 1;
|
||||
}
|
||||
@@ -24,13 +25,15 @@ FDT::FD FDT::open(const Path &p, FileOpts opts) {
|
||||
}
|
||||
|
||||
void FDT::close(FDT::FD fd) {
|
||||
LockGuard l(_mtx);
|
||||
if (auto f = _files.find(fd))
|
||||
if (!f->end)
|
||||
if (f->key == fd) {
|
||||
_files.erase(fd);
|
||||
}
|
||||
}
|
||||
File *FDT::get(FDT::FD fd) {
|
||||
File *FDT::get(FDT::FD fd) const {
|
||||
LockGuard l(_mtx);
|
||||
if (auto f = _files.find(fd))
|
||||
if (!f->end)
|
||||
if (f->key == fd)
|
||||
|
||||
@@ -17,14 +17,14 @@ public:
|
||||
using FD = int64_t;
|
||||
FD open(const Path &p, FileOpts opts);
|
||||
void close(FD fd);
|
||||
File *get(FD fd);
|
||||
File *get(FD fd) const;
|
||||
|
||||
static FDT *current();
|
||||
|
||||
private:
|
||||
SkipList<FD, UniquePtr<File>> _files;
|
||||
int64_t _cur_fd = 10;
|
||||
Mutex _mtx;
|
||||
mutable Mutex _mtx;
|
||||
};
|
||||
|
||||
class FDHandle {
|
||||
|
||||
@@ -9,16 +9,8 @@
|
||||
File::File(Node *node, FileOpts opts) : _n(node), _opts(opts) {
|
||||
if (opts & FileOpts::O_WRONLY)
|
||||
assert(opts & FileOpts::O_RDONLY);
|
||||
if (opts & FileOpts::O_WRONLY)
|
||||
while (!_n->lock_rw()) { yield_self(); }
|
||||
else
|
||||
while (!_n->lock_r()) { yield_self(); }
|
||||
}
|
||||
File::~File() {
|
||||
if (_opts & FileOpts::O_WRONLY)
|
||||
_n->unlock_rw();
|
||||
else
|
||||
_n->unlock_r();
|
||||
}
|
||||
Node *File::node() {
|
||||
return _n;
|
||||
@@ -27,7 +19,7 @@ NodeDir *File::dir() {
|
||||
if (_n && _n->type() == Node::DIR) return static_cast<NodeDir *>(_n);
|
||||
return nullptr;
|
||||
}
|
||||
NodeFile *File::file() {
|
||||
NodeFile *File::file() const {
|
||||
if (_n && _n->type() == Node::FILE) return static_cast<NodeFile *>(_n);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
|
||||
Node *node();
|
||||
NodeDir *dir();
|
||||
NodeFile *file();
|
||||
NodeFile *file() const;
|
||||
|
||||
uint64_t seek(uint64_t pos);
|
||||
uint64_t read(char *buf, uint64_t size);
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
uint64_t size();
|
||||
|
||||
private:
|
||||
Node *_n;
|
||||
Node *const _n;
|
||||
uint64_t _pos = 0;
|
||||
FileOpts _opts;
|
||||
};
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
#include "MemFs.hpp"
|
||||
#include "LockGuard.hpp"
|
||||
|
||||
//FIXME: asserts on read also make sense
|
||||
Vector<Node *> MemFs::MemFsNodeDir::children() {
|
||||
// assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
|
||||
// assert(_lock.owner() == cur_task());
|
||||
LockGuard l(_lock);
|
||||
|
||||
Vector<Node *> out;
|
||||
for (auto c: _children) {
|
||||
@@ -18,21 +16,20 @@ Vector<Node *> MemFs::MemFsNodeDir::children() {
|
||||
}
|
||||
|
||||
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) {
|
||||
assert(_rw_lock.owner() == cur_task());
|
||||
LockGuard l(_lock);
|
||||
auto newnode = new MemFsNodeDir();
|
||||
newnode->_name = name;
|
||||
_children.add(name, newnode);
|
||||
return newnode;
|
||||
}
|
||||
NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) {
|
||||
assert(_rw_lock.owner() == cur_task());
|
||||
LockGuard l(_lock);
|
||||
auto newfile = new MemFsNodeFile(name);
|
||||
_children.add(name, newfile);
|
||||
return newfile;
|
||||
}
|
||||
bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
|
||||
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
|
||||
// assert(_lock.owner() == cur_task());
|
||||
LockGuard l(_lock);
|
||||
if (start >= _bytes.size()) return false;
|
||||
if (start + num > _bytes.size()) return false;
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
@@ -41,8 +38,7 @@ bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
|
||||
return false;
|
||||
}
|
||||
bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
|
||||
assert(_rw_lock.owner() == cur_task());
|
||||
// fixme
|
||||
LockGuard l(_lock);
|
||||
while (_bytes.size() <= start + num) _bytes.emplace_back(0);
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
_bytes[start + i] = buf[i];
|
||||
@@ -50,5 +46,6 @@ bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
|
||||
return true;
|
||||
}
|
||||
size_t MemFs::MemFsNodeFile::size() {
|
||||
LockGuard l(_lock);
|
||||
return _bytes.size();
|
||||
}
|
||||
|
||||
@@ -9,72 +9,36 @@
|
||||
|
||||
Node::~Node() = default;
|
||||
Node *Node::traverse(const Path &path) {
|
||||
while (!lock_r()) { yield_self(); }
|
||||
|
||||
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
|
||||
if (nodeDir._mount) return nodeDir._mount->root()->traverse(path);
|
||||
|
||||
Filesystem *mnt;
|
||||
{
|
||||
LockGuard l(_lock);
|
||||
mnt = nodeDir._mount;
|
||||
}
|
||||
if (mnt) return mnt->root()->traverse(path);
|
||||
|
||||
if (path.empty()) {
|
||||
unlock_r();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (_type == DIR) {
|
||||
|
||||
if (type() == DIR) {
|
||||
// Horribly inefficient
|
||||
auto children = nodeDir.children();
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
if (children[i]->name() == path[0]) {
|
||||
unlock_r();
|
||||
return children[i]->traverse(path.subvector(1, path.size()));
|
||||
}
|
||||
}
|
||||
unlock_r();
|
||||
return nullptr;
|
||||
}
|
||||
unlock_r();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeDir::set_mounted(Filesystem *mount) {
|
||||
LockGuard l(_lock);
|
||||
assert(_type == DIR);
|
||||
assert(_mount == nullptr);
|
||||
_mount = mount;
|
||||
}
|
||||
|
||||
bool Node::lock_r() {
|
||||
LockGuard l(_lock);
|
||||
|
||||
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
|
||||
_r_lock_count++;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool Node::lock_rw() {
|
||||
LockGuard l(_lock);
|
||||
|
||||
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
|
||||
|
||||
if (_r_lock_count != 0 && !(_rw_lock.test() && _rw_lock.owner() == cur_task())) return false;
|
||||
|
||||
if (_rw_lock_count == 0) {
|
||||
assert(!_rw_lock.test());
|
||||
_rw_lock.lock();
|
||||
}
|
||||
|
||||
_rw_lock_count++;
|
||||
|
||||
return true;
|
||||
}
|
||||
void Node::unlock_r() {
|
||||
LockGuard l(_lock);
|
||||
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
|
||||
assert(_r_lock_count > 0);
|
||||
_r_lock_count--;
|
||||
}
|
||||
void Node::unlock_rw() {
|
||||
LockGuard l(_lock);
|
||||
assert(_rw_lock.test() && _rw_lock.owner() == cur_task());
|
||||
assert(_rw_lock_count > 0);
|
||||
_rw_lock_count--;
|
||||
if (_rw_lock_count == 0)
|
||||
_rw_lock.unlock();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define OS2_NODE_HPP
|
||||
|
||||
#include "List.hpp"
|
||||
#include "LockGuard.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
#include "Path.hpp"
|
||||
@@ -23,25 +24,19 @@ public:
|
||||
virtual ~Node() = 0;
|
||||
|
||||
Type type() const { return _type; }
|
||||
const String &name() const { return _name; }
|
||||
const String &name() const {
|
||||
LockGuard l(_lock);
|
||||
return _name;
|
||||
}
|
||||
virtual Node *traverse(const Path &path);
|
||||
|
||||
bool lock_r();
|
||||
bool lock_rw();
|
||||
void unlock_r();
|
||||
void unlock_rw();
|
||||
|
||||
protected:
|
||||
Node(Type type) : _type(type) {}
|
||||
|
||||
Type _type = Type::INVALID;
|
||||
const Type _type = Type::INVALID;
|
||||
|
||||
// This is uuugly
|
||||
Mutex _lock;
|
||||
uint64_t _r_lock_count = 0;
|
||||
uint64_t _rw_lock_count = 0;
|
||||
List<Task *> r_lockers;
|
||||
Mutex _rw_lock;
|
||||
mutable Mutex _lock;
|
||||
|
||||
String _name;
|
||||
Filesystem *_mount = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user