コード例 #1
0
ファイル: pl_funcs.c プロジェクト: 0x0FFF/postgres
static void
free_stmt(PLpgSQL_stmt *stmt)
{
	switch ((enum PLpgSQL_stmt_types) stmt->cmd_type)
	{
		case PLPGSQL_STMT_BLOCK:
			free_block((PLpgSQL_stmt_block *) stmt);
			break;
		case PLPGSQL_STMT_ASSIGN:
			free_assign((PLpgSQL_stmt_assign *) stmt);
			break;
		case PLPGSQL_STMT_IF:
			free_if((PLpgSQL_stmt_if *) stmt);
			break;
		case PLPGSQL_STMT_CASE:
			free_case((PLpgSQL_stmt_case *) stmt);
			break;
		case PLPGSQL_STMT_LOOP:
			free_loop((PLpgSQL_stmt_loop *) stmt);
			break;
		case PLPGSQL_STMT_WHILE:
			free_while((PLpgSQL_stmt_while *) stmt);
			break;
		case PLPGSQL_STMT_FORI:
			free_fori((PLpgSQL_stmt_fori *) stmt);
			break;
		case PLPGSQL_STMT_FORS:
			free_fors((PLpgSQL_stmt_fors *) stmt);
			break;
		case PLPGSQL_STMT_FORC:
			free_forc((PLpgSQL_stmt_forc *) stmt);
			break;
		case PLPGSQL_STMT_FOREACH_A:
			free_foreach_a((PLpgSQL_stmt_foreach_a *) stmt);
			break;
		case PLPGSQL_STMT_EXIT:
			free_exit((PLpgSQL_stmt_exit *) stmt);
			break;
		case PLPGSQL_STMT_RETURN:
			free_return((PLpgSQL_stmt_return *) stmt);
			break;
		case PLPGSQL_STMT_RETURN_NEXT:
			free_return_next((PLpgSQL_stmt_return_next *) stmt);
			break;
		case PLPGSQL_STMT_RETURN_QUERY:
			free_return_query((PLpgSQL_stmt_return_query *) stmt);
			break;
		case PLPGSQL_STMT_RAISE:
			free_raise((PLpgSQL_stmt_raise *) stmt);
			break;
		case PLPGSQL_STMT_ASSERT:
			free_assert((PLpgSQL_stmt_assert *) stmt);
			break;
		case PLPGSQL_STMT_EXECSQL:
			free_execsql((PLpgSQL_stmt_execsql *) stmt);
			break;
		case PLPGSQL_STMT_DYNEXECUTE:
			free_dynexecute((PLpgSQL_stmt_dynexecute *) stmt);
			break;
		case PLPGSQL_STMT_DYNFORS:
			free_dynfors((PLpgSQL_stmt_dynfors *) stmt);
			break;
		case PLPGSQL_STMT_GETDIAG:
			free_getdiag((PLpgSQL_stmt_getdiag *) stmt);
			break;
		case PLPGSQL_STMT_OPEN:
			free_open((PLpgSQL_stmt_open *) stmt);
			break;
		case PLPGSQL_STMT_FETCH:
			free_fetch((PLpgSQL_stmt_fetch *) stmt);
			break;
		case PLPGSQL_STMT_CLOSE:
			free_close((PLpgSQL_stmt_close *) stmt);
			break;
		case PLPGSQL_STMT_PERFORM:
			free_perform((PLpgSQL_stmt_perform *) stmt);
			break;
		default:
			elog(ERROR, "unrecognized cmd_type: %d", stmt->cmd_type);
			break;
	}
}
コード例 #2
0
ファイル: msgcon.c プロジェクト: JamesLinus/vsta
/*
 * msg_connect()
 *	Given a global ID, connect to that port
 *
 * TBD: think about allowing connects to be interrupted.  It makes
 * for some hellishly complex state transitions as you race with
 * the server.
 */
port_t
msg_connect(port_name arg_port, uint arg_mode)
{
	struct proc *p = curthread->t_proc;
	int slot;
	struct portref *pr;
	struct port *port;
	int error = 0;
	struct sysmsg sm;

	/*
	 * Allocate a portref data structure, set it up
	 */
	pr = alloc_portref();

	/*
	 * Set up nodup flag now while it's safe
	 */
	if (arg_mode & ACC_NOCLONE) {
		pr->p_flags |= PF_NODUP;
		arg_mode &= ~ACC_NOCLONE;
	}

	/*
	 * Allocate a system message, fill it in.
	 */
	sm.sm_op = M_CONNECT;
	sm.sm_sender = pr;
	sm.sm_seg[0] = (void *)(p->p_ids);
	sm.sm_nseg = 0;
	sm.sm_arg = arg_mode;
	sm.sm_arg1 = sizeof(p->p_ids);

	/*
	 * Get an open slot
	 */
	if ((slot = alloc_open(p)) < 0) {
		error = -1;
		goto out;
	}

	/*
	 * Now lock name semaphore, and look up our port
	 */
	p_sema(&name_sema, PRIHI);
	port = hash_lookup(portnames, arg_port);
	if (!port) {
		v_sema(&name_sema);
		error = err(ESRCH);
		goto out;
	}

	/*
	 * Lock port
	 */
	p_lock_void(&port->p_lock, SPLHI);

	/*
	 * Fill in port we're trying to attach
	 */
	pr->p_port = port;

	/*
	 * Free up semaphores we don't need to hold any more
	 */
	v_sema(&name_sema);

	/*
	 * Queue our message onto the server's queue, kick him awake
	 */
	lqueue_msg(port, &sm);

	/*
	 * Release lock and fall asleep on our own semaphore
	 */
	p_sema_v_lock(&pr->p_iowait, PRIHI, &port->p_lock);

	/*
	 * If p_port went away, we raced with him closing
	 */
	if (!pr->p_port) {
		error = err(EIO);
	}

	/*
	 * If p_state hasn't been set to IODONE, then the connect failed.
	 * The reason has been placed in m_err field of our sysmsg.
	 */
	else if (pr->p_state != PS_IODONE) {
		error = err(sm.sm_err);
	}

	/*
	 * If no error, move port state to PS_IODONE and let
	 * it go into service
	 */
	if (error == 0) {
		p->p_open[slot] = pr;
		error = slot;
		pr = 0;		/* So not freed below */
		slot = -1;
	}

	/*
	 * All done.  Release references as needed, return
	 */
out:
	if (slot >= 0) {
		free_open(p, slot);
	}
	if (pr) {
		FREE(pr, MT_PORTREF);
	}
	return(error);
}