コード例 #1
0
ファイル: update.c プロジェクト: scolobb/unionmount
static void
_root_update_thread ()
{
  error_t err;
  
  while (1)
    {
      if (hurd_condition_wait (&update_wakeup, &update_lock))
	mutex_unlock (&update_lock);

      rwlock_writer_lock (&update_rwlock);

      do 
	{
	  ulfs_check();
	  err = node_init_root (netfs_root_node);
	}
      while (err == ENOENT);

      if (err)
	{
	  fprintf (stderr, "update thread: got a %s\n", strerror (err));
	}

      ncache_reset ();

      rwlock_writer_unlock (&update_rwlock);
    }
}
コード例 #2
0
static error_t
repeater_select (struct protid *cred, mach_port_t reply,
		 mach_msg_type_name_t replytype, int *type)
{
  if (!cred)
    return EOPNOTSUPP;

  if (*type & ~SELECT_READ)
    return EINVAL;

  if (*type == 0)
    return 0;
  
  mutex_lock (&global_lock);
  while (1)
    {
      if (mousebuf.size > 0)
	{
	  *type = SELECT_READ;
	  mutex_unlock (&global_lock);

	  return 0;
	}

      ports_interrupt_self_on_port_death (cred, reply);
      if (hurd_condition_wait (&select_alert, &global_lock))
	{
	  *type = 0;
	  mutex_unlock (&global_lock);

	  return EINTR;
	}
    }
}
コード例 #3
0
ファイル: hurdio.c プロジェクト: diegonc/console-xkb-support
/* Assert the DTR if necessary.  Must be called with global lock held.  */
static void
wait_for_dtr (void)
{
  while (!assert_dtr)
    hurd_condition_wait (&hurdio_assert_dtr_condition, &global_lock);
  assert_dtr = 0;

  if (tty_arg == 0)
    ioport = termctl->underlying;
  else
    {
      /* Open the file in blocking mode, so that the carrier is
	 established as well.  */
      ioport = file_name_lookup (tty_arg, O_READ|O_WRITE, 0);
      if (ioport == MACH_PORT_NULL)
	{
	  report_carrier_error (errno);
	  return;
	}
    }


  error_t err;
  struct termios state = termstate;

  /* Assume that we have a full blown terminal initially.  */
  tioc_caps = ~0;

  /* Set terminal in raw mode etc.  */
  err = hurdio_set_bits (&state);
  if (err)
    report_carrier_error (err);
  else
    {
      termstate = state;

      /* Signal that we have a carrier.  */
      report_carrier_on ();

      /* Signal that the writer thread should resume its work.  */
      condition_broadcast (&hurdio_writer_condition);
    }
}
コード例 #4
0
/* Place the mouse event EVNT in the mouse event buffer.  */
static void
repeat_event (kd_event *evt)
{
  kd_event *ev;

  mutex_lock (&global_lock);
  while (mousebuf.size + sizeof (kd_event) > MOUSEBUFSZ)
    {
      /* The input buffer is full, wait until there is some space.  */
      if (hurd_condition_wait (&mousebuf.writecond, &global_lock))
	{
	  mutex_unlock (&global_lock);
	  /* Interrupt, silently continue.  */
	}
    }
  ev = (kd_event *) &mousebuf.evtbuffer[MOUSEBUF_POS (mousebuf.pos 
						      + mousebuf.size)];
  mousebuf.size += sizeof (kd_event);
  memcpy (ev, evt, sizeof (kd_event));
  
  condition_broadcast (&mousebuf.readcond);
  mutex_unlock (&global_lock);
}
コード例 #5
0
ファイル: wait.c プロジェクト: diegonc/console-xkb-support
kern_return_t
S_proc_wait (struct proc *p,
	     mach_port_t reply_port,
	     mach_msg_type_name_t reply_port_type,
	     pid_t pid,
	     int options,
	     int *status,
	     int *sigcode,
	     struct rusage *ru,
	     pid_t *pid_status)
{
  int cancel;

  int reap (struct proc *child)
    {
      if (child->p_waited
	  || (!child->p_dead
	      && (!child->p_stopped
		  || !(child->p_traced || (options & WUNTRACED)))))
	return 0;
      child->p_waited = 1;
      *status = child->p_status;
      *sigcode = child->p_sigcode;
      *ru = child->p_rusage; /* all zeros if !p_dead */
      *pid_status = child->p_pid;
      if (child->p_dead)
	complete_exit (child);
      return 1;
    }

  if (!p)
    return EOPNOTSUPP;

 start_over:
  /* See if we can satisfy the request with a stopped
     child; also check for invalid arguments here. */
  if (!p->p_ochild)
    return ECHILD;

  if (pid > 0)
    {
      struct proc *child = pid_find_allow_zombie (pid);
      if (!child || child->p_parent != p)
	return ECHILD;
      if (reap (child))
	return 0;
    }
  else
    {
      struct proc *child;
      int had_a_match = pid == 0;

      for (child = p->p_ochild; child; child = child->p_sib)
	if (waiter_cares (pid, p->p_pgrp->pg_pgid,
			  child->p_pid, child->p_pgrp->pg_pgid))
	  {
	    if (reap (child))
	      return 0;
	    had_a_match = 1;
	  }

      if (!had_a_match)
	return ECHILD;
    }

  if (options & WNOHANG)
    return EWOULDBLOCK;

  p->p_waiting = 1;
  cancel = hurd_condition_wait (&p->p_wakeup, &global_lock);
  if (p->p_dead)
    return EOPNOTSUPP;
  if (cancel)
    return EINTR;
  goto start_over;
}
コード例 #6
0
ファイル: hurdio.c プロジェクト: diegonc/console-xkb-support
/* Output characters.  */
static any_t
hurdio_writer_loop (any_t arg)
{
  /* XXX The output buffer has 256 bytes.  */
#define BUFFER_SIZE 256
  char *bufp;
  char pending_output[BUFFER_SIZE];
  size_t amount;
  error_t err;
  int size;
  int npending_output_copy;
  mach_port_t ioport_copy;

  mutex_lock (&global_lock);
  writer_thread = mach_thread_self ();

  while (1)
    {
      while (writer_thread != MACH_PORT_NULL
	     && (ioport == MACH_PORT_NULL || !qsize (outputq)
		 || output_stopped))
	hurd_condition_wait (&hurdio_writer_condition, &global_lock);
      if (writer_thread == MACH_PORT_NULL) /* A sign to die.  */
	return 0;

      /* Copy characters onto PENDING_OUTPUT, not bothering
	 those already there. */
      size = qsize (outputq);

      if (size + npending_output > BUFFER_SIZE)
	size = BUFFER_SIZE - npending_output;

      bufp = pending_output + npending_output;
      npending_output += size;
      /* We need to save these values, as otherwise there are races
	 with hurdio_abandon_physical_output or hurdio_desert_dtr,
	 which might overwrite the static variables.  */
      npending_output_copy = npending_output;
      ioport_copy = ioport;
      mach_port_mod_refs (mach_task_self (), ioport_copy,
			  MACH_PORT_RIGHT_SEND, 1);

      while (size--)
	*bufp++ = dequeue (outputq);

      /* Submit all the outstanding characters to the I/O port.  */
      mutex_unlock (&global_lock);
      err = io_write (ioport_copy, pending_output, npending_output_copy,
		      -1, &amount);
      mutex_lock (&global_lock);

      mach_port_mod_refs (mach_task_self (), ioport_copy,
			  MACH_PORT_RIGHT_SEND, -1);
      if (err)
	hurdio_desert_dtr ();
      else
	{
	  /* Note that npending_output might be set to null in the
	     meantime by hurdio_abandon_physical_output.  */
	  if (amount >= npending_output)
	    {
	      npending_output = 0;
	      condition_broadcast (outputq->wait);
	    }
	  else
	    {
	      /* Copy the characters that didn't get output
		 to the front of the array.  */
	      npending_output -= amount;
	      memmove (pending_output, pending_output + amount,
		       npending_output);
	    }
	}
    }
#undef BUFFER_SIZE

  return 0;
}
コード例 #7
0
static error_t
repeater_read (struct protid *cred, char **data,
	       mach_msg_type_number_t *datalen, off_t offset,
	       mach_msg_type_number_t amount)
{
  /* Deny access if they have bad credentials. */
  if (! cred)
    return EOPNOTSUPP;
  else if (! (cred->po->openstat & O_READ))
    return EBADF;
  
  mutex_lock (&global_lock);
  while (!mousebuf.size)
    {
      if (cred->po->openstat & O_NONBLOCK && mousebuf.size == 0)
	{
	  mutex_unlock (&global_lock);
	  return EWOULDBLOCK;
	}
      
      if (hurd_condition_wait (&mousebuf.readcond, &global_lock))
	{
	  mutex_unlock (&global_lock);
	  return EINTR;
	}
    }
  
  amount = (amount / sizeof (kd_event) - 1) * sizeof (kd_event);
  if (amount > mousebuf.size)
    amount = mousebuf.size;
  
  if (amount > 0)
    {
      char *mousedata;
      unsigned int i = 0;

      /* Allocate a buffer when this is required.  */
      if (*datalen < amount)
	{
	  *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
	  if (*data == MAP_FAILED)
	    {
	      mutex_unlock (&global_lock);
	      return ENOMEM;
	    }
	}
      
      /* Copy the bytes to the user's buffer and remove them from the
	 mouse events buffer.  */
      mousedata = *data;
      while (i != amount)
	{
	  mousedata[i++] = mousebuf.evtbuffer[mousebuf.pos++];
	  mousebuf.pos = MOUSEBUF_POS (mousebuf.pos);
	}
      mousebuf.size -= amount;
      condition_broadcast (&mousebuf.writecond);
    }
  
  *datalen = amount;
  mutex_unlock (&global_lock);

  return 0;
}