/*===========================================================================* * handle_work * *===========================================================================*/ static void handle_work(void *(*func)(void *arg)) { /* Handle asynchronous device replies and new system calls. If the originating * endpoint is an FS endpoint, take extra care not to get in deadlock. */ struct vmnt *vmp = NULL; endpoint_t proc_e; proc_e = m_in.m_source; if (fp->fp_flags & FP_SYS_PROC) { if (worker_available() == 0) { if (!deadlock_resolving) { if ((vmp = find_vmnt(proc_e)) != NULL) { /* A call back or dev result from an FS * endpoint. Set call back flag. Can do only * one call back at a time. */ if (vmp->m_flags & VMNT_CALLBACK) { reply(proc_e, EAGAIN); return; } vmp->m_flags |= VMNT_CALLBACK; /* When an FS endpoint has to make a call back * in order to mount, force its device to a * "none device" so block reads/writes will be * handled by ROOT_FS_E. */ if (vmp->m_flags & VMNT_MOUNTING) vmp->m_flags |= VMNT_FORCEROOTBSF; } deadlock_resolving = 1; dl_worker_start(func); return; } /* Already trying to resolve a deadlock, can't * handle more, sorry */ reply(proc_e, EAGAIN); return; } } worker_start(func); }
/*===========================================================================* * handle_work * *===========================================================================*/ static void handle_work(void (*func)(void)) { /* Handle asynchronous device replies and new system calls. If the originating * endpoint is an FS endpoint, take extra care not to get in deadlock. */ struct vmnt *vmp = NULL; endpoint_t proc_e; int use_spare = FALSE; proc_e = m_in.m_source; if (fp->fp_flags & FP_SRV_PROC) { vmp = find_vmnt(proc_e); if (vmp != NULL) { /* A callback from an FS endpoint. Can do only one at once. */ if (vmp->m_flags & VMNT_CALLBACK) { replycode(proc_e, EAGAIN); return; } /* Already trying to resolve a deadlock? Can't handle more. */ if (worker_available() == 0) { replycode(proc_e, EAGAIN); return; } /* A thread is available. Set callback flag. */ vmp->m_flags |= VMNT_CALLBACK; if (vmp->m_flags & VMNT_MOUNTING) { vmp->m_flags |= VMNT_FORCEROOTBSF; } } /* Use the spare thread to handle this request if needed. */ use_spare = TRUE; } worker_start(fp, func, &m_in, use_spare); }