Beispiel #1
0
/*===========================================================================*
 *			       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);
}
Beispiel #2
0
/*===========================================================================*
 *			       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);
}