コード例 #1
0
ファイル: gen_trap.c プロジェクト: rohsaini/mkunity
/*
 * This message server catches server exceptions. It runs in a dedicated thread.
 */
void *
server_exception_catcher(
	void	*arg)
{
	struct server_thread_priv_data	priv_data;
	kern_return_t			kr;
#define MSG_BUFFER_SIZE	8192
	union request_msg {
		mach_msg_header_t	hdr;
		mig_reply_error_t	death_pill;
		char			space[MSG_BUFFER_SIZE];
	} *msg_buffer_1, *msg_buffer_2;
	mach_msg_header_t		*request;
	mig_reply_error_t		*reply;

	cthread_set_name(cthread_self(), "server exc catcher");
	server_thread_set_priv_data(cthread_self(), &priv_data);

	kr = vm_allocate(mach_task_self(),
			 (vm_address_t *) &msg_buffer_1,
			 2 * sizeof *msg_buffer_1,
			 TRUE);
	if (kr != KERN_SUCCESS) {
		MACH3_DEBUG(0, kr, ("server_exception_catcher: vm_allocate"));
		panic("server_exception_catcher");
	}

	msg_buffer_2 = msg_buffer_1 + 1;
	request = &msg_buffer_1->hdr;
	reply = &msg_buffer_2->death_pill;

	do {
		kr = mach_msg(request, MACH_RCV_MSG,
			      0, sizeof *msg_buffer_1,
			      server_exception_port,
			      MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
		if (kr != MACH_MSG_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("server_exception_catcher: mach_msg"));
			panic("server_exception_catcher: receive");
		}

		if (exc_server(request, &reply->Head)) {}
		else {
			printk("server_exception_catcher: invalid message"
			       "(id = %d = 0x%x)\n",
			       request->msgh_id, request->msgh_id);
		}
		panic("server_exception_catcher: what now ?");
	} while (1);
       
	cthread_detach(cthread_self());
	cthread_exit((void *) 0);
	/*NOTREACHED*/
	return (void *) 0;
}
コード例 #2
0
ファイル: server_thread.c プロジェクト: rohsaini/mkunity
void *
server_thread_bootstrap(
	void *dummy)
{
	struct server_thread_priv_data	priv_data;
	void **args;
	int (*fn)(void *);
	void *arg;
	struct task_struct *tsk;
	int ret;
	osfmach3_jmp_buf jmp_buf;
	extern int sys_exit(int error_code);

	args = (void **) dummy;
	fn = (int(*)(void *)) args[0];
	arg = args[1];
	tsk = (struct task_struct *) args[2];

	cthread_set_name(cthread_self(), "kernel thread");
	server_thread_set_priv_data(cthread_self(), &priv_data);
	priv_data.current_task = tsk;
#if 0	/* XXX ? */
	tsk->osfmach3.thread->mach_thread_port = mach_thread_self();
#endif
	tsk->osfmach3.thread->under_server_control = TRUE;
	tsk->osfmach3.thread->active_on_cthread = cthread_self();

	uniproc_enter();

	priv_data.jmp_buf = &jmp_buf;
	if (osfmach3_setjmp(priv_data.jmp_buf)) {
		/*
		 * The kernel thread is being terminated.
		 */
		uniproc_exit();
		cthread_set_name(cthread_self(), "dead kernel thread");
		cthread_detach(cthread_self());
		cthread_exit((void *) 0);
		/*NOTREACHED*/
		panic("server_thread_bootstrap: the zombie cthread walks !\n");
	}

	kfree(args);
	while (current->state != TASK_RUNNING) {
		schedule();	/* wait until we're resumed by our parent */
	}
	ret = (*fn)(arg);
	sys_exit(ret);

	/*NOTREACHED*/
	panic("server_thread_bootstrap: the zombie kernel thread walks !\n");
}
コード例 #3
0
ファイル: gen_trap.c プロジェクト: rohsaini/mkunity
/*
 * This message server catches user task exceptions. Most user exceptions
 * will be received on the thread exception port. This server servers
 * only exceptions from unknown threads or from external debuggers.
 * It runs in a dedicated thread.
 */
void *
task_exception_catcher(
	void	*arg)
{
	struct server_thread_priv_data	priv_data;
	kern_return_t			kr;
#define MSG_BUFFER_SIZE	8192
	union request_msg {
		mach_msg_header_t	hdr;
		mig_reply_error_t	death_pill;
		char			space[MSG_BUFFER_SIZE];
	} *msg_buffer_1, *msg_buffer_2;
	mach_msg_header_t		*request;
	mig_reply_error_t		*reply;
	mach_msg_header_t		*tmp;

	cthread_set_name(cthread_self(), "task exc catcher");
	server_thread_set_priv_data(cthread_self(), &priv_data);

	uniproc_enter();

	kr = vm_allocate(mach_task_self(),
			 (vm_address_t *) &msg_buffer_1,
			 2 * sizeof *msg_buffer_1,
			 TRUE);
	if (kr != KERN_SUCCESS) {
		MACH3_DEBUG(0, kr, ("task_exception_catcher: vm_allocate"));
		panic("task_exception_catcher");
	}

	msg_buffer_2 = msg_buffer_1 + 1;
	request = &msg_buffer_1->hdr;
	reply = &msg_buffer_2->death_pill;

	do {
		uniproc_exit();
		kr = mach_msg(request, MACH_RCV_MSG,
			      0, sizeof *msg_buffer_1,
			      user_trap_port,
			      MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
		if (kr != MACH_MSG_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("task_exception_catcher: mach_msg"));
			panic("task_exception_catcher: receive");
		}
		uniproc_enter();

		if (exc_server(request, &reply->Head)) {}
		else {
			printk("trap_exception_catcher: invalid message"
			       "(id = %d = 0x%x)\n",
			       request->msgh_id, request->msgh_id);
		}

		if (reply->Head.msgh_remote_port == MACH_PORT_NULL) {
			/* no reply port, just get another request */
			continue;
		}
		if (!(reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
		    reply->RetCode == MIG_NO_REPLY) {
			/* deallocate reply port right */
			(void) mach_port_deallocate(mach_task_self(),
						    reply->Head.msgh_remote_port);
			continue;
		}

		/* Send reply to request and receive another */
		uniproc_exit();
		kr = mach_msg(&reply->Head,
			      MACH_SEND_MSG,
			      reply->Head.msgh_size,
			      0,
			      MACH_PORT_NULL,
			      MACH_MSG_TIMEOUT_NONE,
			      MACH_PORT_NULL);
		uniproc_enter();

		if (kr != MACH_MSG_SUCCESS) {
			if (kr == MACH_SEND_INVALID_DEST) {
				/* deallocate reply port right */
				/* XXX should destroy reply msg */
				(void) mach_port_deallocate(mach_task_self(),
							    reply->Head.msgh_remote_port);
			} else {
				MACH3_DEBUG(0, kr, ("mach_msg"));
				panic("task_exception_catcher: send");
			}
		}

		tmp = request;
		request = (mach_msg_header_t *) reply;
		reply = (mig_reply_error_t *) tmp;

	} while (1);
       
	cthread_detach(cthread_self());
	cthread_exit((void *) 0);
	/*NOTREACHED*/
	return (void *) 0;
}
コード例 #4
0
ファイル: thr_cthreads.c プロジェクト: 1ack/Impala
void 
ldap_pvt_thread_exit( void *retval )
{
	cthread_exit( (any_t) retval );
}
コード例 #5
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
void *
serial_read_thread(
	void	*arg)
{
	struct server_thread_priv_data	priv_data;
	kern_return_t			kr;
	struct async_struct	*info;
	int				line, wait_loop, count;
	io_buf_ptr_inband_t		inbuf;		/* 128 chars */
	mach_msg_type_number_t		data_count;
	mach_port_t			device_port;

	cthread_set_name(cthread_self(), "serial read");
	server_thread_set_priv_data(cthread_self(), &priv_data);

	line = (int) arg;
	info = rs_table + line;
	uniproc_enter();
	device_port = info->device_port;

	for (;;) {
		data_count = sizeof inbuf;
		uniproc_exit();
		kr = device_read_inband(device_port,
					0,	/* mode */
					0,	/* recnum */
					sizeof inbuf,
					inbuf,
					&data_count);
		uniproc_enter();

		if (kr == D_OUT_OF_BAND) {
			serial_handle_oob_event(info, device_port);
			continue;
		} else if (kr != D_SUCCESS) {
			/* Something happened.. simply shutdown the line.. */
			if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
                           (info->flags & ASYNC_CALLOUT_NOHUP))) 
                       		queue_task_irq_off(&info->tqueue_hangup, &tq_scheduler);
			uniproc_exit();
			cthread_detach(cthread_self());
			cthread_exit((void *) 0);
			/* NEVER REACHED */
		}

		if (data_count <= 0) 
			continue;

		/*
		 * Its very possible with the Power Mac
		 * to overflow the Linux TTY buffers.
		 * (A serial interrupt can present up to
		 * 8K worth of data in one shot)
		 *
		 * The following loops attempts to give the
		 * PPP line disc. a chance to clear the queue
		 * out.
		 */

		for (wait_loop = 0; wait_loop < 6; wait_loop++) {
			/* Check to make sure the tty did not
			 * go away..
			 */

			if (info->tty == NULL)
				break;

			if ((info->tty->flip.count+data_count) < TTY_FLIPBUF_SIZE)
				break;

			/* Try to give another thread some time.. */
			osfmach3_yield();
		}

		if (info->tty == NULL)
			continue;

		count = MIN(TTY_FLIPBUF_SIZE + info->tty->flip.count, data_count);
		if (count <= 0)
			continue;

		info->last_active = jiffies; 
		info->tty->flip.count += count;
		memcpy(info->tty->flip.char_buf_ptr, inbuf, count);
		memset(info->tty->flip.flag_buf_ptr, 0, count);
		info->tty->flip.flag_buf_ptr += count;
		info->tty->flip.char_buf_ptr += count;
		queue_task_irq_off(&info->tty->flip.tqueue, &tq_timer);
	}
}