A file class

上级 aaada9c3
#pragma once
#include "cpputil.hh" #include "cpputil.hh"
#include "ns.hh" #include "ns.hh"
#include "gc.hh" #include "gc.hh"
...@@ -6,8 +8,14 @@ ...@@ -6,8 +8,14 @@
u64 namehash(const strbuf<DIRSIZ>&); u64 namehash(const strbuf<DIRSIZ>&);
struct file { struct file {
enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET } type; file() : type(file::FD_NONE), readable(0), writable(0),
std::atomic<int> ref; // reference count socket(0), pipe(nullptr), ip(nullptr), off(0),
ref_(1) {}
file *dup();
void close();
enum { FD_NONE, FD_PIPE, FD_INODE, FD_SOCKET } type;
char readable; char readable;
char writable; char writable;
...@@ -15,8 +23,11 @@ struct file { ...@@ -15,8 +23,11 @@ struct file {
struct pipe *pipe; struct pipe *pipe;
struct inode *ip; struct inode *ip;
u32 off; u32 off;
}; NEW_DELETE_OPS(file);
private:
std::atomic<int> ref_;
};
// in-core file system types // in-core file system types
......
...@@ -10,7 +10,7 @@ public: ...@@ -10,7 +10,7 @@ public:
filetable(const filetable &f) : ref_(1) { filetable(const filetable &f) : ref_(1) {
for(int fd = 0; fd < NOFILE; fd++) { for(int fd = 0; fd < NOFILE; fd++) {
if (f.ofile_[fd]) if (f.ofile_[fd])
ofile_[fd] = filedup(f.ofile_[fd]); ofile_[fd] = f.ofile_[fd]->dup();
else else
ofile_[fd] = nullptr; ofile_[fd] = nullptr;
} }
...@@ -19,7 +19,7 @@ public: ...@@ -19,7 +19,7 @@ public:
~filetable() { ~filetable() {
for(int fd = 0; fd < NOFILE; fd++){ for(int fd = 0; fd < NOFILE; fd++){
if (ofile_[fd]){ if (ofile_[fd]){
fileclose(ofile_[fd]); ofile_[fd]->close();
ofile_[fd] = 0; ofile_[fd] = 0;
} }
} }
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
void close(int fd) { void close(int fd) {
struct file *f = ofile_[fd]; struct file *f = ofile_[fd];
ofile_[fd] = nullptr; ofile_[fd] = nullptr;
fileclose(f); f->close();
} }
void decref() { void decref() {
......
#pragma once
// On-disk file system format. // On-disk file system format.
// Both the kernel and user programs use this header file. // Both the kernel and user programs use this header file.
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include "spinlock.h" #include "spinlock.h"
#include "atomic.hh" #include "atomic.hh"
#include "cpputil.hh" #include "cpputil.hh"
#include "fs.h"
#include "file.hh"
#include "filetable.hh" #include "filetable.hh"
// Saved registers for kernel context switches. // Saved registers for kernel context switches.
......
...@@ -9,41 +9,29 @@ ...@@ -9,41 +9,29 @@
struct devsw __mpalign__ devsw[NDEV]; struct devsw __mpalign__ devsw[NDEV];
// Allocate a file structure. void
struct file* file::close(void)
filealloc(void)
{ {
struct file *f = (file*) kmalloc(sizeof(struct file)); if (--ref_ > 0)
f->ref = 1; return;
f->type = file::FD_NONE;
return f;
}
// Increment ref count for file f. if(type == file::FD_PIPE)
struct file* pipeclose(pipe, writable);
filedup(struct file *f) else if(type == file::FD_INODE)
{ iput(ip);
if (f->ref++ < 1) else if(type == file::FD_SOCKET)
panic("filedup"); netclose(socket);
return f; else if(type != file::FD_NONE)
panic("file::close bad type");
delete this;
} }
// Close file f. (Decrement ref count, close when reaches 0.) file*
void file::dup(void)
fileclose(struct file *f)
{ {
if (--f->ref > 0) if (ref_++ < 1)
return; panic("file::dup");
return this;
if(f->type == file::FD_PIPE)
pipeclose(f->pipe, f->writable);
else if(f->type == file::FD_INODE)
iput(f->ip);
else if(f->type == file::FD_SOCKET)
netclose(f->socket);
else if(f->type != file::FD_NONE)
panic("fileclose bad type");
kmfree(f, sizeof(struct file));
} }
// Get metadata about file f. // Get metadata about file f.
......
...@@ -28,7 +28,7 @@ pipealloc(struct file **f0, struct file **f1) ...@@ -28,7 +28,7 @@ pipealloc(struct file **f0, struct file **f1)
p = 0; p = 0;
*f0 = *f1 = 0; *f0 = *f1 = 0;
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) if((*f0 = new file()) == 0 || (*f1 = new file()) == 0)
goto bad; goto bad;
if((p = (pipe*)kmalloc(sizeof(*p))) == 0) if((p = (pipe*)kmalloc(sizeof(*p))) == 0)
goto bad; goto bad;
...@@ -55,9 +55,9 @@ pipealloc(struct file **f0, struct file **f1) ...@@ -55,9 +55,9 @@ pipealloc(struct file **f0, struct file **f1)
kmfree((char*)p, sizeof(*p)); kmfree((char*)p, sizeof(*p));
} }
if(*f0) if(*f0)
fileclose(*f0); (*f0)->close();
if(*f1) if(*f1)
fileclose(*f1); (*f1)->close();
return -1; return -1;
} }
......
...@@ -44,7 +44,7 @@ sys_dup(int ofd) ...@@ -44,7 +44,7 @@ sys_dup(int ofd)
return -1; return -1;
if((fd=fdalloc(f)) < 0) if((fd=fdalloc(f)) < 0)
return -1; return -1;
filedup(f); f->dup();
return fd; return fd;
} }
...@@ -317,9 +317,9 @@ sys_openat(int dirfd, const char *path, int omode) ...@@ -317,9 +317,9 @@ sys_openat(int dirfd, const char *path, int omode)
} }
} }
if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){ if((f = new file()) == 0 || (fd = fdalloc(f)) < 0){
if(f) if(f)
fileclose(f); f->close();
iunlockput(ip); iunlockput(ip);
return -1; return -1;
} }
...@@ -416,7 +416,7 @@ sys_pipe(int *fd) ...@@ -416,7 +416,7 @@ sys_pipe(int *fd)
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
if(fd0 >= 0) if(fd0 >= 0)
myproc()->ftable->close(fd0); myproc()->ftable->close(fd0);
fileclose(wf); wf->close();
return -1; return -1;
} }
fd[0] = fd0; fd[0] = fd0;
...@@ -449,13 +449,13 @@ allocsocket(struct file **rf, int *rfd) ...@@ -449,13 +449,13 @@ allocsocket(struct file **rf, int *rfd)
struct file *f; struct file *f;
int fd; int fd;
f = filealloc(); f = new file();
if (f == nullptr) if (f == nullptr)
return -1; return -1;
fd = fdalloc(f); fd = fdalloc(f);
if (fd < 0) { if (fd < 0) {
fileclose(f); f->close();
return fd; return fd;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论