Cleanup more resources upon exit
This commit is contained in:
parent
1c928cf61a
commit
90cde23c19
@ -343,7 +343,7 @@ PRIVATE void *do_pending_pipe(void *arg)
|
|||||||
fp->fp_buffer, fp->fp_nbytes);
|
fp->fp_buffer, fp->fp_nbytes);
|
||||||
|
|
||||||
if (r != SUSPEND) /* Do we have results to report? */
|
if (r != SUSPEND) /* Do we have results to report? */
|
||||||
(void) reply(who_e, r);
|
reply(who_e, r);
|
||||||
|
|
||||||
unlock_filp(f);
|
unlock_filp(f);
|
||||||
|
|
||||||
@ -431,18 +431,7 @@ PRIVATE void *do_work(void *arg)
|
|||||||
if (fp->fp_wtid == dl_worker.w_tid)
|
if (fp->fp_wtid == dl_worker.w_tid)
|
||||||
deadlock_resolving = 0;
|
deadlock_resolving = 0;
|
||||||
}
|
}
|
||||||
if (reply(who_e, error) != OK) {
|
reply(who_e, error);
|
||||||
if ((vmp = find_vmnt(who_e)) != NULL) {
|
|
||||||
for (i = 0; i < NR_PROCS; i++) {
|
|
||||||
rfp = &fproc[i];
|
|
||||||
if (rfp->fp_task == vmp->m_fs_e) {
|
|
||||||
/* We found a process waiting for a
|
|
||||||
* reply from non-responsive FS */
|
|
||||||
worker_stop(worker_get(rfp->fp_wtid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_cleanup(fp);
|
thread_cleanup(fp);
|
||||||
@ -764,7 +753,7 @@ PRIVATE void get_work()
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* reply *
|
* reply *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int reply(whom, result)
|
PUBLIC void reply(whom, result)
|
||||||
int whom; /* process to reply to */
|
int whom; /* process to reply to */
|
||||||
int result; /* result of the call (usually OK or error #) */
|
int result; /* result of the call (usually OK or error #) */
|
||||||
{
|
{
|
||||||
@ -776,7 +765,6 @@ int result; /* result of the call (usually OK or error #) */
|
|||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
printf("VFS: couldn't send reply %d to %d: %d\n", result, whom, r);
|
printf("VFS: couldn't send reply %d to %d: %d\n", result, whom, r);
|
||||||
}
|
}
|
||||||
return(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -457,6 +457,8 @@ PRIVATE void free_proc(struct fproc *exiter, int flags)
|
|||||||
*/
|
*/
|
||||||
unsuspend_by_endpt(exiter->fp_endpoint);
|
unsuspend_by_endpt(exiter->fp_endpoint);
|
||||||
dmap_unmap_by_endpt(exiter->fp_endpoint);
|
dmap_unmap_by_endpt(exiter->fp_endpoint);
|
||||||
|
vmnt_unmap_by_endpt(exiter->fp_endpoint);
|
||||||
|
worker_stop_by_endpt(exiter->fp_endpoint);
|
||||||
|
|
||||||
/* Release root and working directories. */
|
/* Release root and working directories. */
|
||||||
if (exiter->fp_rd) { put_vnode(exiter->fp_rd); exiter->fp_rd = NULL; }
|
if (exiter->fp_rd) { put_vnode(exiter->fp_rd); exiter->fp_rd = NULL; }
|
||||||
|
@ -116,7 +116,7 @@ _PROTOTYPE( void lock_revive, (void) );
|
|||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
_PROTOTYPE( int main, (void) );
|
_PROTOTYPE( int main, (void) );
|
||||||
_PROTOTYPE( int reply, (int whom, int result) );
|
_PROTOTYPE( void reply, (int whom, int result) );
|
||||||
_PROTOTYPE( void lock_proc, (struct fproc *rfp, int force_lock) );
|
_PROTOTYPE( void lock_proc, (struct fproc *rfp, int force_lock) );
|
||||||
_PROTOTYPE( void unlock_proc, (struct fproc *rfp) );
|
_PROTOTYPE( void unlock_proc, (struct fproc *rfp) );
|
||||||
_PROTOTYPE( void *do_dummy, (void *arg) );
|
_PROTOTYPE( void *do_dummy, (void *arg) );
|
||||||
@ -323,6 +323,7 @@ _PROTOTYPE( struct vmnt *get_locked_vmnt, (struct fproc *rfp) );
|
|||||||
_PROTOTYPE( void init_vmnts, (void) );
|
_PROTOTYPE( void init_vmnts, (void) );
|
||||||
_PROTOTYPE( int lock_vmnt, (struct vmnt *vp, tll_access_t locktype) );
|
_PROTOTYPE( int lock_vmnt, (struct vmnt *vp, tll_access_t locktype) );
|
||||||
_PROTOTYPE( void unlock_vmnt, (struct vmnt *vp) );
|
_PROTOTYPE( void unlock_vmnt, (struct vmnt *vp) );
|
||||||
|
_PROTOTYPE( void vmnt_unmap_by_endpt, (endpoint_t proc_e) );
|
||||||
|
|
||||||
/* vnode.c */
|
/* vnode.c */
|
||||||
_PROTOTYPE( void check_vnode_locks, (void) );
|
_PROTOTYPE( void check_vnode_locks, (void) );
|
||||||
|
@ -556,6 +556,7 @@ PUBLIC int req_mknod(
|
|||||||
PUBLIC int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
|
PUBLIC int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
int r;
|
||||||
|
|
||||||
/* Fill in request message */
|
/* Fill in request message */
|
||||||
m.m_type = REQ_MOUNTPOINT;
|
m.m_type = REQ_MOUNTPOINT;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "fproc.h"
|
#include "fproc.h"
|
||||||
|
|
||||||
FORWARD _PROTOTYPE( int is_vmnt_locked, (struct vmnt *vmp) );
|
FORWARD _PROTOTYPE( int is_vmnt_locked, (struct vmnt *vmp) );
|
||||||
|
FORWARD _PROTOTYPE( void clear_vmnt, (struct vmnt *vmp) );
|
||||||
|
|
||||||
/* Is vmp pointer reasonable? */
|
/* Is vmp pointer reasonable? */
|
||||||
#define SANEVMP(v) ((((v) >= &vmnt[0] && (v) < &vmnt[NR_MNTS])))
|
#define SANEVMP(v) ((((v) >= &vmnt[0] && (v) < &vmnt[NR_MNTS])))
|
||||||
@ -58,6 +59,25 @@ PUBLIC void check_vmnt_locks()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* clear_vmnt *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE void clear_vmnt(struct vmnt *vmp)
|
||||||
|
{
|
||||||
|
/* Reset vmp to initial parameters */
|
||||||
|
ASSERTVMP(vmp);
|
||||||
|
|
||||||
|
vmp->m_fs_e = NONE;
|
||||||
|
vmp->m_dev = NO_DEV;
|
||||||
|
vmp->m_flags = 0;
|
||||||
|
vmp->m_mounted_on = NULL;
|
||||||
|
vmp->m_root_node = NULL;
|
||||||
|
vmp->m_label[0] = '\0';
|
||||||
|
vmp->m_comm.c_max_reqs = 1;
|
||||||
|
vmp->m_comm.c_cur_reqs = 0;
|
||||||
|
vmp->m_comm.c_req_queue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* get_free_vmnt *
|
* get_free_vmnt *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -92,19 +112,11 @@ PUBLIC struct vmnt *find_vmnt(endpoint_t fs_e)
|
|||||||
PUBLIC void init_vmnts(void)
|
PUBLIC void init_vmnts(void)
|
||||||
{
|
{
|
||||||
/* Initialize vmnt table */
|
/* Initialize vmnt table */
|
||||||
struct vmnt *vp;
|
struct vmnt *vmp;
|
||||||
|
|
||||||
for (vp = &vmnt[0]; vp < &vmnt[NR_MNTS]; vp++) {
|
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
|
||||||
vp->m_fs_e = NONE;
|
clear_vmnt(vmp);
|
||||||
vp->m_dev = NO_DEV;
|
tll_init(&vmp->m_lock);
|
||||||
vp->m_flags = 0;
|
|
||||||
vp->m_mounted_on = NULL;
|
|
||||||
vp->m_root_node = NULL;
|
|
||||||
vp->m_label[0] = '\0';
|
|
||||||
vp->m_comm.c_max_reqs = 1;
|
|
||||||
vp->m_comm.c_cur_reqs = 0;
|
|
||||||
vp->m_comm.c_req_queue = NULL;
|
|
||||||
tll_init(&vp->m_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,3 +180,15 @@ PUBLIC void unlock_vmnt(struct vmnt *vmp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* vmnt_unmap_by_endpoint *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC void vmnt_unmap_by_endpt(endpoint_t proc_e)
|
||||||
|
{
|
||||||
|
struct vmnt *vmp;
|
||||||
|
|
||||||
|
if ((vmp = find_vmnt(proc_e)) != NULL)
|
||||||
|
clear_vmnt(vmp);
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@ FORWARD _PROTOTYPE( void get_work, (struct worker_thread *worker) );
|
|||||||
FORWARD _PROTOTYPE( void *worker_main, (void *arg) );
|
FORWARD _PROTOTYPE( void *worker_main, (void *arg) );
|
||||||
FORWARD _PROTOTYPE( void worker_sleep, (struct worker_thread *worker) );
|
FORWARD _PROTOTYPE( void worker_sleep, (struct worker_thread *worker) );
|
||||||
FORWARD _PROTOTYPE( void worker_wake, (struct worker_thread *worker) );
|
FORWARD _PROTOTYPE( void worker_wake, (struct worker_thread *worker) );
|
||||||
|
FORWARD _PROTOTYPE( int worker_waiting_for, (struct worker_thread *worker,
|
||||||
|
endpoint_t proc_e) );
|
||||||
PRIVATE int init = 0;
|
PRIVATE int init = 0;
|
||||||
PRIVATE mthread_attr_t tattr;
|
PRIVATE mthread_attr_t tattr;
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ PRIVATE mthread_attr_t tattr;
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* worker_init *
|
* worker_init *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void worker_init(struct worker_thread *worker)
|
PUBLIC void worker_init(struct worker_thread *wp)
|
||||||
{
|
{
|
||||||
/* Initialize worker thread */
|
/* Initialize worker thread */
|
||||||
if (!init) {
|
if (!init) {
|
||||||
@ -40,13 +42,13 @@ PUBLIC void worker_init(struct worker_thread *worker)
|
|||||||
init = 1;
|
init = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERTW(worker);
|
ASSERTW(wp);
|
||||||
|
|
||||||
worker->w_job.j_func = NULL; /* Mark not in use */
|
wp->w_job.j_func = NULL; /* Mark not in use */
|
||||||
worker->w_next = NULL;
|
wp->w_next = NULL;
|
||||||
assert(mutex_init(&worker->w_event_mutex, NULL) == 0);
|
assert(mutex_init(&wp->w_event_mutex, NULL) == 0);
|
||||||
assert(cond_init(&worker->w_event, NULL) == 0);
|
assert(cond_init(&wp->w_event, NULL) == 0);
|
||||||
assert(mthread_create(&worker->w_tid, &tattr, worker_main, (void *) worker) == 0);
|
assert(mthread_create(&wp->w_tid, &tattr, worker_main, (void *) wp) == 0);
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,10 +294,30 @@ PUBLIC void worker_signal(struct worker_thread *worker)
|
|||||||
PUBLIC void worker_stop(struct worker_thread *worker)
|
PUBLIC void worker_stop(struct worker_thread *worker)
|
||||||
{
|
{
|
||||||
ASSERTW(worker); /* Make sure we have a valid thread */
|
ASSERTW(worker); /* Make sure we have a valid thread */
|
||||||
worker->w_job.j_m_in.m_type = -EIO;
|
worker->w_job.j_m_in.m_type = EIO;
|
||||||
worker_wake(worker);
|
worker_wake(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* worker_stop_by_endpt *
|
||||||
|
*===========================================================================*/
|
||||||
|
PUBLIC void worker_stop_by_endpt(endpoint_t proc_e)
|
||||||
|
{
|
||||||
|
struct worker_thread *worker;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (proc_e == NONE) return;
|
||||||
|
|
||||||
|
if (worker_waiting_for(&sys_worker, proc_e)) worker_stop(&sys_worker);
|
||||||
|
if (worker_waiting_for(&dl_worker, proc_e)) worker_stop(&dl_worker);
|
||||||
|
|
||||||
|
for (i = 0; i < NR_WTHREADS; i++) {
|
||||||
|
worker = &workers[i];
|
||||||
|
if (worker_waiting_for(worker, proc_e))
|
||||||
|
worker_stop(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* worker_self *
|
* worker_self *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -344,3 +366,19 @@ PUBLIC struct job *worker_getjob(thread_t worker_tid)
|
|||||||
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* worker_waiting_for *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int worker_waiting_for(struct worker_thread *worker, endpoint_t proc_e)
|
||||||
|
{
|
||||||
|
ASSERTW(worker); /* Make sure we have a valid thread */
|
||||||
|
|
||||||
|
if (worker->w_job.j_func != NULL) {
|
||||||
|
if (worker->w_job.j_fp != NULL) {
|
||||||
|
return(worker->w_job.j_fp->fp_task == proc_e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user