示例#1
0
apr_status_t port_socket_close0(port_t *self)
{
	port_socket_data_t *data = self->data;
	process_t *proc = proc_lookup(pid_serial(self->owner_in));
	if (proc)
	{
		xpool_t *tmp = xpool_make(self->pool);
		int len = buffer_len(data->in_buf);
		term_t msg;

		if (len > 0)
		{
			term_t bin = make_binary(intnum(len), buffer_ptr(data->in_buf), tmp);
			
			msg = make_tuple3(A_TCP, port_id(self, tmp), bin, tmp);
			proc_new_mail(proc, msg);
			buffer_clear(data->in_buf);
		}

		msg = make_tuple2(A_TCP_CLOSED, port_id(self, tmp), tmp);
		proc_new_mail(proc, msg);
		xpool_destroy(tmp);
	}

	return apr_socket_close(data->sock);
}
示例#2
0
term_t bif_run_slice2(term_t Pid, term_t Reductions, process_t *ctx)
{
	process_t *proc;
	term_t retval, retval1;
	term_t res;
	if (!is_pid(Pid) || !is_int(Reductions))
		return A_BADARG;
	proc = proc_lookup(pid_serial(Pid));
	res = proc_main(proc, int_value2(Reductions), &retval);

	if (res == AI_DONE)
	{
		//proc_destroy(proc);
		//- process should not be destroyed now
		//- as we may need to notify links first

		retval1 = marshal_term(retval, proc_gc_pool(ctx));
		result(make_tuple2(AI_DONE, retval1, proc_gc_pool(ctx)));
	}
	else
	{
		if (res == AI_YIELD)
			result(res);
		else
		{
			retval1 = marshal_term(retval, proc_gc_pool(ctx));
			result(make_tuple2(res, retval1, proc_gc_pool(ctx)));
		}
	}

	return AI_OK;
}
示例#3
0
apr_status_t port_socket_do_writable(port_t *self)
{
	port_socket_data_t *data = self->data;

	if (data->is_connecting)
	{
		process_t *proc = proc_lookup(pid_serial(self->owner_in));	  // owner_in
		if (proc)
		{
			xpool_t *tmp = xpool_make(self->pool);
			term_t msg = make_tuple2(A_TCP_CONNECTED, port_id(self, tmp), tmp);
			proc_new_mail(proc, msg);
			xpool_destroy(tmp);
		}

		data->is_connecting = 0;
	}

	if (buffer_len(data->out_buf) > 0)
	{
		apr_status_t rs;
		rs = buffer_socket_send(data->out_buf, data->sock);
		if (rs != 0)
			return rs;
	}

    if (data->is_closing && buffer_len(data->out_buf) == 0)
		return APR_EOF;	//make poll close0 the socket

	if (data->space_required && buffer_available(data->out_buf) >= data->required_size)
	{
		xpool_t *tmp = xpool_make(self->pool);
		int avail = buffer_available(data->out_buf);
		term_t msg = make_tuple3(A_TCP_SPACE, port_id(self, tmp), intnum(avail), tmp);
		process_t *proc = proc_lookup(pid_serial(self->owner_out));

		//TODO: insure that only owner can send to socket

		proc_new_mail(proc, msg);
		xpool_destroy(tmp);

		data->space_required = 0;
	}

	return APR_SUCCESS;
}
示例#4
0
term_t bif_destroy_process1(term_t Pid, process_t *ctx)
{
	process_t *proc;
	if (!is_pid(Pid))
		return A_BADARG;
	proc = proc_lookup(pid_serial(Pid));
	if (proc)
		proc_destroy(proc);
	result(A_TRUE);
	return AI_OK;
}
示例#5
0
apr_status_t ol_listener_close0(outlet_t *self)
{
	ol_listener_data_t *data = self->data;
	
	if (data->is_accepting)
	{
		proc_t *proc = scheduler_lookup(data->teevm->scheduler, pid_serial(data->reply_to_pid));
		term_t msg = heap_tuple2(proc->heap, A_TCP_CLOSED, outlet_id(self));
		scheduler_new_local_mail(data->teevm->scheduler, proc, msg);

		data->is_accepting = 0;
	}

	apr_socket_close(data->sock);
	outlet_mall_kick_out(data->teevm->mall, self);
	apr_pool_destroy(self->pool);

	return APR_SUCCESS;
}
示例#6
0
apr_status_t ol_listener_do_readable(outlet_t *self)
{
	apr_status_t rs;
	ol_listener_data_t *data = self->data;
	proc_t *proc;
	
	proc = scheduler_lookup(data->teevm->scheduler, pid_serial(data->reply_to_pid));
	if (proc)
	{
		apr_socket_t *new_sock;
		outlet_t *new_outlet;
		term_t msg;

		apr_pool_t *p;
		apr_pool_create(&p, 0);

		rs = apr_socket_accept(&new_sock, data->sock, p);
		if (rs == 0)
			rs = apr_socket_opt_set(new_sock, APR_SO_NONBLOCK, 1);

		if (rs != 0)
		{
			apr_pool_destroy(p);
			return rs;
		}

		new_outlet = ol_socket_make(new_sock, 0);

		//put to poll ring
		outlet_mall_allot(data->teevm->mall, new_outlet);

		//messages delivered to caller of accept
		new_outlet->owner_in = new_outlet->owner_out = proc;

		msg = heap_tuple3(proc->heap, A_TCP_ACCEPTED, outlet_id(self), outlet_id(new_outlet));
		scheduler_new_local_mail(data->teevm->scheduler, proc, msg);
	}

	data->is_accepting = 0;

	return APR_SUCCESS;
}
示例#7
0
apr_status_t port_socket_do_readable(port_t *self)
{
	apr_status_t rs;
	port_socket_data_t *data = self->data;

	rs = buffer_socket_recv(data->in_buf, data->sock);
	if (rs == 0)
	{
		if (data->packet_expected)
		{
			process_t *proc;
			int len = buffer_len(data->in_buf);

			if (data->expected_size == 0 ||
				data->expected_size > 0 && len >= data->expected_size)
			{

				if (data->expected_size > 0)
					len = data->expected_size;

				proc = proc_lookup(pid_serial(self->owner_in));
				if (proc)
				{
					xpool_t *tmp = xpool_make(self->pool);
					term_t bin = make_binary(intnum(len), buffer_ptr(data->in_buf), tmp);
					term_t msg = make_tuple3(A_TCP, port_id(self, tmp), bin, tmp);
					proc_new_mail(proc, msg);
					buffer_consume(data->in_buf, len);
					xpool_destroy(tmp);
				}

				data->packet_expected = 0;
				data->expected_size = 0;
			}
		}
	}

	return rs;
}
示例#8
0
static int
pdisplay1(fmtfn_t to, void *to_arg, Process* p, Eterm obj)
{
    int i, k;
    Eterm* nobj;

    if (dcount-- <= 0)
	return(1);

    if (is_CP(obj)) {
	erts_print(to, to_arg, "<cp/header:%0*lX",PTR_SIZE,obj);
	return 0;
    }

    switch (tag_val_def(obj)) {
    case NIL_DEF:
	erts_print(to, to_arg, "[]");
	break;
    case ATOM_DEF:
	erts_print(to, to_arg, "%T", obj);
	break;
    case SMALL_DEF:
	erts_print(to, to_arg, "%ld", signed_val(obj));
	break;

    case BIG_DEF:
	nobj = big_val(obj);
	if (!IN_HEAP(p, nobj)) {
	    erts_print(to, to_arg, "#<bad big %X>#", obj);
	    return 1;
	}

	i = BIG_SIZE(nobj);
	if (BIG_SIGN(nobj))
	    erts_print(to, to_arg, "-#integer(%d) = {", i);
	else
	    erts_print(to, to_arg, "#integer(%d) = {", i);
	erts_print(to, to_arg, "%d", BIG_DIGIT(nobj, 0));
	for (k = 1; k < i; k++)
	    erts_print(to, to_arg, ",%d", BIG_DIGIT(nobj, k));
	erts_putc(to, to_arg, '}');
	break;
    case REF_DEF:
    case EXTERNAL_REF_DEF: {
	Uint32 *ref_num;
	erts_print(to, to_arg, "#Ref<%lu", ref_channel_no(obj));
	ref_num = ref_numbers(obj);
	for (i = ref_no_numbers(obj)-1; i >= 0; i--)
	    erts_print(to, to_arg, ",%lu", ref_num[i]);
	erts_print(to, to_arg, ">");
	break;
    }
    case PID_DEF:
    case EXTERNAL_PID_DEF:
	erts_print(to, to_arg, "<%lu.%lu.%lu>",
		   pid_channel_no(obj),
		   pid_number(obj),
		   pid_serial(obj));
	break;
    case PORT_DEF:
    case EXTERNAL_PORT_DEF:
	erts_print(to, to_arg, "#Port<%lu.%lu>",
		   port_channel_no(obj),
		   port_number(obj));
	break;
    case LIST_DEF:
	erts_putc(to, to_arg, '[');
	nobj = list_val(obj);
	while (1) {
	    if (!IN_HEAP(p, nobj)) {
		erts_print(to, to_arg, "#<bad list %X>", obj);
		return 1;
	    }
	    if (pdisplay1(to, to_arg, p, *nobj++) != 0)
		return(1);
	    if (is_not_list(*nobj))
		break;
	    erts_putc(to, to_arg, ',');
	    nobj = list_val(*nobj);
	}
	if (is_not_nil(*nobj)) {
	    erts_putc(to, to_arg, '|');
	    if (pdisplay1(to, to_arg, p, *nobj) != 0)
		return(1);
	}
	erts_putc(to, to_arg, ']');
	break;
    case TUPLE_DEF:
	nobj = tuple_val(obj);	/* pointer to arity */
	i = arityval(*nobj);	/* arity */
	erts_putc(to, to_arg, '{');
	while (i--) {
	    if (pdisplay1(to, to_arg, p, *++nobj) != 0) return(1);
	    if (i >= 1) erts_putc(to, to_arg, ',');
	}
	erts_putc(to, to_arg, '}');
	break;
    case FLOAT_DEF: {
	    FloatDef ff;
	    GET_DOUBLE(obj, ff);
	    erts_print(to, to_arg, "%.20e", ff.fd);
	}
	break;
    case BINARY_DEF:
	erts_print(to, to_arg, "#Bin");
	break;
    case MATCHSTATE_DEF:
        erts_print(to, to_arg, "#Matchstate");
        break;
    default:
	erts_print(to, to_arg, "unknown object %x", obj);
    }
    return(0);
}
示例#9
0
static void dump_memory_map_to_stream(FILE *fp)
{
    ErtsAlcType_t n;
    MapStatBlock_t *bp;
    int lock = !ERTS_IS_CRASH_DUMPING;
    if (lock) {
	ASSERT(!erts_is_allctr_wrapper_prelocked());
	erts_mtx_lock(&instr_mutex);
    }

    /* Write header */

    fprintf(fp,
	    "{instr_hdr,\n"
	    " %lu,\n"
	    " %lu,\n"
	    " {",
	    (unsigned long) ERTS_INSTR_VSN,
	    (unsigned long) MAP_STAT_BLOCK_HEADER_SIZE);

#if ERTS_ALC_N_MIN != 1
#error ERTS_ALC_N_MIN is not 1
#endif

    for (n = ERTS_ALC_N_MIN; n <= ERTS_ALC_N_MAX; n++) {
	ErtsAlcType_t t = ERTS_ALC_N2T(n);
	ErtsAlcType_t a = ERTS_ALC_T2A(t);
	ErtsAlcType_t c = ERTS_ALC_T2C(t);
	const char *astr;

	if (erts_allctrs_info[a].enabled)
	    astr = ERTS_ALC_A2AD(a);
	else
	    astr = ERTS_ALC_A2AD(ERTS_ALC_A_SYSTEM);

	fprintf(fp,
		"%s{%s,%s,%s}%s",
		(n == ERTS_ALC_N_MIN) ? "" : "  ",
		ERTS_ALC_N2TD(n),
		astr,
		ERTS_ALC_C2CD(c),
		(n == ERTS_ALC_N_MAX) ? "" : ",\n");
    }

    fprintf(fp, "}}.\n");

    /* Write memory data */
    for (bp = mem_anchor; bp; bp = bp->next) {
	if (is_internal_pid(bp->pid))
	    fprintf(fp,
		    "{%lu, %lu, %lu, {%lu,%lu,%lu}}.\n",
		    (UWord) bp->type_no,
		    (UWord) bp->mem,
		    (UWord) bp->size,
		    (UWord) pid_channel_no(bp->pid),
		    (UWord) pid_number(bp->pid),
		    (UWord) pid_serial(bp->pid));
	else
	    fprintf(fp,
		    "{%lu, %lu, %lu, undefined}.\n",
		    (UWord) bp->type_no,
		    (UWord) bp->mem,
		    (UWord) bp->size);
    }

    if (lock)
	erts_mtx_unlock(&instr_mutex);
}
示例#10
0
apr_status_t port_socket_set_option(port_t *self, term_t opt, term_t value)
{
	port_socket_data_t *data = self->data;
	if (opt == A_EXPECT)
	{
		if (!is_int(value))
			return APR_BADARG;
		data->expected_size = int_value2(value);
		if (data->expected_size < 0)
			return APR_BADARG;

		if (!is_pid(self->owner_in))
			return APR_ENOPROC;

		//enough data may already be there
		if (data->expected_size == 0 && buffer_len(data->in_buf) > 0 ||
			data->expected_size > 0 && buffer_len(data->in_buf) >= data->expected_size)
		{
			int len = (data->expected_size == 0)
				?buffer_len(data->in_buf)
				:data->expected_size;
			xpool_t *tmp = xpool_make(self->pool);
			term_t bin = make_binary(intnum(len), buffer_ptr(data->in_buf), tmp);
			term_t msg = make_tuple3(A_TCP, port_id(self, tmp), bin, tmp);
			process_t *proc = proc_lookup(pid_serial(self->owner_in));

			proc_new_mail(proc, msg);
			buffer_consume(data->in_buf, len);
			xpool_destroy(tmp);
		}
		else
			data->packet_expected = 1;
	}
	else if (opt == A_REQUIRE)
	{
		int size;
		if (!is_int(value))
			return APR_BADARG;
		size = int_value2(value);
		if (size < 0 || size > SOCK_OUTBUF_LEN)
			return APR_BADARG;

		data->required_size = size;

		if (buffer_available(data->out_buf) >= size)
		{
			xpool_t *tmp = xpool_make(self->pool);
			int avail = buffer_available(data->out_buf);
			term_t msg = make_tuple3(A_TCP_SPACE, port_id(self, tmp), intnum(avail), tmp);
			process_t *proc = proc_lookup(pid_serial(self->owner_out));

			//TODO: insure that only owner can send to socket

			proc_new_mail(proc, msg);
			xpool_destroy(tmp);

			data->space_required = 0;
		}
		else
			data->space_required = 1;
	}
	else
		return APR_BADARG;
	return APR_SUCCESS;
}