A filetable class

上级 e4afcf9f
#include "atomic.hh"
class filetable {
public:
filetable() : ref_(1) {
for(int fd = 0; fd < NOFILE; fd++)
ofile_[fd] = nullptr;
}
filetable(const filetable &f) : ref_(1) {
for(int fd = 0; fd < NOFILE; fd++) {
if (f.ofile_[fd])
ofile_[fd] = filedup(f.ofile_[fd]);
else
ofile_[fd] = nullptr;
}
}
~filetable() {
for(int fd = 0; fd < NOFILE; fd++){
if (ofile_[fd]){
fileclose(ofile_[fd]);
ofile_[fd] = 0;
}
}
}
struct file *getfile(int fd) {
if (fd < 0 || fd >= NOFILE)
return nullptr;
return ofile_[fd];
}
int allocfd(struct file *f) {
for (int fd = 0; fd < NOFILE; fd++){
if (ofile_[fd] == nullptr){
ofile_[fd] = f;
return fd;
}
}
return -1;
}
void close(int fd) {
struct file *f = ofile_[fd];
ofile_[fd] = nullptr;
fileclose(f);
}
void decref() {
if (--ref_ == 0)
delete this;
}
void incref() {
ref_++;
}
NEW_DELETE_OPS(filetable)
private:
struct file *ofile_[NOFILE];
std::atomic<u64> ref_;
};
......@@ -3,6 +3,7 @@
#include "spinlock.h"
#include "atomic.hh"
#include "cpputil.hh"
#include "filetable.hh"
// Saved registers for kernel context switches.
// (also implicitly defined in swtch.S)
......@@ -47,7 +48,7 @@ struct proc : public rcu_freed {
struct trapframe *tf; // Trap frame for current syscall
struct context *context; // swtch() here to run process
int killed; // If non-zero, have been killed
struct file *ofile[NOFILE]; // Open files
filetable *ftable;
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
u64 tsc;
......
......@@ -72,9 +72,9 @@ sys_async(int fd, size_t count, off_t off,
msg = &ipcctl->msg[msgid];
ubuf = (kshared+PGSIZE+(pageid*PGSIZE));
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
if ((f = myproc()->ftable->getfile(fd)) == nullptr)
return -1;
if(f->type != file::FD_INODE)
if (f->type != file::FD_INODE)
return -1;
f->ip->ref++;
......
......@@ -38,7 +38,7 @@ enum { sched_debug = 0 };
proc::proc(int npid) :
rcu_freed("proc"), vmap(0), brk(0), kstack(0),
pid(npid), parent(0), tf(0), context(0), killed(0),
cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
on_runq(-1), cpu_pin(0), runq(0), oncv(0), cv_wakeup(0),
user_fs_(0), state_(EMBRYO)
{
......@@ -48,7 +48,6 @@ proc::proc(int npid) :
memset(&childq, 0, sizeof(childq));
memset(&child_next, 0, sizeof(child_next));
memset(ofile, 0, sizeof(ofile));
memset(&runqlink, 0, sizeof(runqlink));
memset(&cv_waiters, 0, sizeof(cv_waiters));
memset(&cv_sleep, 0, sizeof(cv_sleep));
......@@ -122,19 +121,13 @@ void
exit(void)
{
struct proc *p, *np;
int fd;
int wakeupinit;
if(myproc() == bootproc)
panic("init exiting");
// Close all open files.
for(fd = 0; fd < NOFILE; fd++){
if(myproc()->ofile[fd]){
fileclose(myproc()->ofile[fd]);
myproc()->ofile[fd] = 0;
}
}
if (myproc()->ftable)
myproc()->ftable->decref();
// Kernel threads might not have a cwd
if (myproc()->cwd != nullptr) {
......@@ -246,6 +239,9 @@ inituser(void)
extern u64 _initcode_size;
p = allocproc();
p->ftable = new filetable();
if (p->ftable == nullptr)
panic("userinit: new filetable");
bootproc = p;
if((p->vmap = new vmap()) == 0)
panic("userinit: out of vmaps?");
......@@ -432,7 +428,7 @@ procdumpall(void)
int
fork(int flags)
{
int i, pid;
int pid;
struct proc *np;
int cow = 1;
......@@ -464,9 +460,13 @@ fork(int flags)
// Clear %eax so that fork returns 0 in the child.
np->tf->rax = 0;
for(i = 0; i < NOFILE; i++)
if(myproc()->ofile[i])
np->ofile[i] = filedup(myproc()->ofile[i]);
np->ftable = new filetable(*myproc()->ftable);
if (np->ftable == nullptr) {
// XXX(sbw) leaking?
freeproc(np);
return -1;
}
np->cwd = idup(myproc()->cwd);
pid = np->pid;
safestrcpy(np->name, myproc()->name, sizeof(myproc()->name));
......
......@@ -19,7 +19,7 @@ argfd(int fd, struct file **pf)
{
struct file *f;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
if((f = myproc()->ftable->getfile(fd)) == nullptr)
return -1;
if(pf)
*pf = f;
......@@ -31,15 +31,7 @@ argfd(int fd, struct file **pf)
static int
fdalloc(struct file *f)
{
int fd;
for(fd = 0; fd < NOFILE; fd++){
if(myproc()->ofile[fd] == 0){
myproc()->ofile[fd] = f;
return fd;
}
}
return -1;
return myproc()->ftable->allocfd(f);
}
long
......@@ -73,7 +65,7 @@ sys_pread(int fd, void *ubuf, size_t count, off_t offset)
uptr i = (uptr)ubuf;
int r;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
if ((f = myproc()->ftable->getfile(fd)) == nullptr)
return -1;
for(uptr va = PGROUNDDOWN(i); va < i+count; va = va + PGSIZE)
......@@ -108,8 +100,7 @@ sys_close(int fd)
if(argfd(fd, &f) < 0)
return -1;
myproc()->ofile[fd] = 0;
fileclose(f);
myproc()->ftable->close(fd);
return 0;
}
......@@ -296,7 +287,7 @@ sys_openat(int dirfd, const char *path, int omode)
} else if (dirfd < 0 || dirfd >= NOFILE) {
return -1;
} else {
struct file *fdir = myproc()->ofile[dirfd];
struct file *fdir = myproc()->ftable->getfile(dirfd);
if (fdir == nullptr || fdir->type != file::FD_INODE)
return -1;
cwd = fdir->ip;
......@@ -424,8 +415,7 @@ sys_pipe(int *fd)
fd0 = -1;
if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){
if(fd0 >= 0)
myproc()->ofile[fd0] = 0;
fileclose(rf);
myproc()->ftable->close(fd0);
fileclose(wf);
return -1;
}
......@@ -437,15 +427,14 @@ sys_pipe(int *fd)
static void
freesocket(int fd)
{
fileclose(myproc()->ofile[fd]);
myproc()->ofile[fd] = 0;
myproc()->ftable->close(fd);
}
static int
getsocket(int fd, struct file **ret)
{
struct file *f;
if (fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
if ((f = myproc()->ftable->getfile(fd)) == nullptr)
return -1;
if (f->type != file::FD_SOCKET)
return -1;
......@@ -493,8 +482,7 @@ sys_socket(int domain, int type, int protocol)
s = netsocket(domain, type, protocol);
if (s < 0) {
myproc()->ofile[fd] = 0;
fileclose(f);
myproc()->ftable->close(fd);
return s;
}
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论