Exemplo n.º 1
0
/*===========================================================================*
 *			       do_pending_pipe				     *
 *===========================================================================*/
static void do_pending_pipe(void)
{
  int r, op;
  struct filp *f;
  tll_access_t locktype;

  f = fp->fp_filp[fp->fp_fd];
  assert(f != NULL);

  locktype = (job_call_nr == VFS_READ) ? VNODE_READ : VNODE_WRITE;
  op = (job_call_nr == VFS_READ) ? READING : WRITING;
  lock_filp(f, locktype);

  r = rw_pipe(op, who_e, f, fp->fp_io_buffer, fp->fp_io_nbytes);

  if (r != SUSPEND) { /* Do we have results to report? */
	/* Process is writing, but there is no reader. Send a SIGPIPE signal.
	 * This should match the corresponding code in read_write().
	 */
	if (r == EPIPE && op == WRITING) {
		if (!(f->filp_flags & O_NOSIGPIPE))
			sys_kill(fp->fp_endpoint, SIGPIPE);
	}

	replycode(fp->fp_endpoint, r);
  }

  unlock_filp(f);
}
Exemplo n.º 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);
}
/*===========================================================================*
 *			       do_pending_pipe				     *
 *===========================================================================*/
static void do_pending_pipe(void)
{
  vir_bytes buf;
  size_t nbytes, cum_io;
  int r, op, fd;
  struct filp *f;
  tll_access_t locktype;

  assert(fp->fp_blocked_on == FP_BLOCKED_ON_NONE);

  /*
   * We take all our needed resumption state from the m_in message, which is
   * filled by unblock().  Since this is an internal resumption, there is no
   * need to perform extensive checks on the message fields.
   */
  fd = job_m_in.m_lc_vfs_readwrite.fd;
  buf = job_m_in.m_lc_vfs_readwrite.buf;
  nbytes = job_m_in.m_lc_vfs_readwrite.len;
  cum_io = job_m_in.m_lc_vfs_readwrite.cum_io;

  f = fp->fp_filp[fd];
  assert(f != NULL);

  locktype = (job_call_nr == VFS_READ) ? VNODE_READ : VNODE_WRITE;
  op = (job_call_nr == VFS_READ) ? READING : WRITING;
  lock_filp(f, locktype);

  r = rw_pipe(op, who_e, f, job_call_nr, fd, buf, nbytes, cum_io);

  if (r != SUSPEND) { /* Do we have results to report? */
	/* Process is writing, but there is no reader. Send a SIGPIPE signal.
	 * This should match the corresponding code in read_write().
	 */
	if (r == EPIPE && op == WRITING) {
		if (!(f->filp_flags & O_NOSIGPIPE))
			sys_kill(fp->fp_endpoint, SIGPIPE);
	}

	replycode(fp->fp_endpoint, r);
  }

  unlock_filp(f);
}