Пример #1
0
/* Prepare a wakeup message.  */
static error_t
create_wakeupmsg (struct __pthread *thread)
{
  kern_return_t err;

  /* Build wakeup message.  */
  thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
  thread->wakeupmsg.msgh_size = 0;

  err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
			      &thread->wakeupmsg.msgh_remote_port);
  if (err)
    return EAGAIN;

  thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL;
  thread->wakeupmsg.msgh_seqno = 0;
  thread->wakeupmsg.msgh_id = 0;

  err = __mach_port_insert_right (__mach_task_self (),
				  thread->wakeupmsg.msgh_remote_port,
				  thread->wakeupmsg.msgh_remote_port,
				  MACH_MSG_TYPE_MAKE_SEND);
  if (err)
    {
      __mach_port_destroy (__mach_task_self (),
			   thread->wakeupmsg.msgh_remote_port);
      return EAGAIN;
    }

  return 0;
}
Пример #2
0
void
_hurdsig_fault_init (void)
{
  error_t err;
  struct machine_thread_state state;
  mach_port_t sigexc;

  /* Allocate a port to receive signal thread exceptions.
     We will move this receive right to the proc server.  */
  err = __mach_port_allocate (__mach_task_self (),
			      MACH_PORT_RIGHT_RECEIVE, &sigexc);
  assert_perror (err);
  err = __mach_port_allocate (__mach_task_self (),
			      MACH_PORT_RIGHT_RECEIVE, &forward_sigexc);
  assert_perror (err);

  /* Allocate a port to receive the exception msgs forwarded
     from the proc server.  */
  err = __mach_port_insert_right (__mach_task_self (), sigexc,
				  sigexc, MACH_MSG_TYPE_MAKE_SEND);
  assert_perror (err);

  /* Set the queue limit for this port to just one.  The proc server will
     notice if we ever get a second exception while one remains queued and
     unreceived, and decide we are hopelessly buggy.  */
#ifdef MACH_PORT_RECEIVE_STATUS_COUNT
  {
    const mach_port_limits_t lim = { mpl_qlimit: 1 };
    assert (MACH_PORT_RECEIVE_STATUS_COUNT == sizeof lim / sizeof (natural_t));
    err = __mach_port_set_attributes (__mach_task_self (), forward_sigexc,
				      MACH_PORT_RECEIVE_STATUS,
				      (mach_port_info_t) &lim,
				      MACH_PORT_RECEIVE_STATUS_COUNT);
  }
#else
  err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1);
#endif
  assert_perror (err);

  /* This state will be restored when we fault.
     It runs the function above.  */
  memset (&state, 0, sizeof state);
  MACHINE_THREAD_STATE_SET_PC (&state, faulted);
  MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);

  err = __USEPORT
    (PROC,
     __proc_handle_exceptions (port,
			       sigexc,
			       forward_sigexc, MACH_MSG_TYPE_MAKE_SEND,
			       MACHINE_THREAD_STATE_FLAVOR,
			       (natural_t *) &state,
			       MACHINE_THREAD_STATE_COUNT));
  assert_perror (err);

  /* Direct signal thread exceptions to the proc server.  */
#ifdef THREAD_EXCEPTION_PORT
  err = __thread_set_special_port (_hurd_msgport_thread,
				   THREAD_EXCEPTION_PORT, sigexc);
#elif defined (EXC_MASK_ALL)
  __thread_set_exception_ports (_hurd_msgport_thread,
				EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
						 | EXC_MASK_MACH_SYSCALL
						 | EXC_MASK_RPC_ALERT),
				sigexc,
				EXCEPTION_STATE_IDENTITY,
				MACHINE_THREAD_STATE);
#else
# error thread_set_exception_ports?
#endif
  __mach_port_deallocate (__mach_task_self (), sigexc);
  assert_perror (err);
}