Ejemplo n.º 1
0
int32_t context_lua_t::context_query_yield_finalize(lua_State *root_coro, lua_State *main_coro, void *userdata, uint32_t destination)
{
	if (root_coro != NULL) {
		context_lua_t* lctx = context_lua_t::lua_get_context(root_coro);
		message_t& message = lctx->get_yielding_message();
		message.m_session = context_lua_t::lua_ref_yield_coroutine(root_coro);
		bool ret;
		if (message_is_string(message)) {
			ret = singleton_ref(node_lua_t).context_send_string_safe(destination, lctx->get_handle(), message.m_session, CONTEXT_QUERY, message_string(message));
		} else if (message_is_bson(message)) {

		} else {
			ret = singleton_ref(node_lua_t).context_send(destination, message);
		}
		if (ret) {
			int64_t timeout = lctx->get_yielding_timeout();
			if (timeout > 0) {
				context_lua_t::lua_ref_timer(main_coro, message.m_session, timeout, 0, false);
			}
			return UV_OK;
		} else {
			lua_free_ref_session(main_coro, message.m_session);
			return NL_ENOCONTEXT;
		}
	}
	return UV_OK;
}
Ejemplo n.º 2
0
void uv_udp_handle_t::write(request_udp_write_t& request)
{
	int32_t err = UV_UNKNOWN;
	if (request.m_shared_write) {
		uv_udp_handle_t* handle = (uv_udp_handle_t*)singleton_ref(network_t).get_shared_write_socket(request.m_socket_fd);
		if (handle != NULL) {
			uint32_t length = request.m_length > 0 ? request.m_length : (uint32_t)buffer_data_length(request.m_buffer);
			if (uv_is_closing((uv_handle_t*)handle)) {
				err = NL_EUDPSCLOSED;
			} else {
				err = handle->write_handle(request);
			}
		} else {
			err = NL_EUDPNOWSHARED;
		}
	} else {
		err = request.m_socket_handle->write_handle(request);
	}
	if (err != UV_OK) { /* write error had been occurred */
		if (request.m_length > 0) {
			nl_free((void*)request.m_string);
		} else {
			buffer_release(request.m_buffer);
		}
		if (request.m_session != LUA_REFNIL) {
			singleton_ref(node_lua_t).context_send(request.m_source, 0, request.m_session, RESPONSE_UDP_WRITE, (nl_err_code)err);
		}
	}
}
Ejemplo n.º 3
0
void uv_udp_handle_t::read(request_udp_read_t& request)
{
	if (!m_read_started) {
		if (uv_udp_recv_start((uv_udp_t*)m_handle, on_read_alloc, on_read) != 0) {
			singleton_ref(node_lua_t).context_send(m_source, 0, m_lua_ref, RESPONSE_UDP_READ, singleton_ref(network_t).last_error());
			return;
		}
		m_read_started = true;
	}
}
Ejemplo n.º 4
0
void uv_udp_handle_t::set_udp_wshared(bool enable)
{
	if (!uv_is_closing((uv_handle_t*)(m_handle))) {
		int64_t fd = SOCKET_MAKE_FD(m_lua_ref, m_source);
		if (enable) {
			singleton_ref(network_t).put_shared_write_socket(fd, this);
		} else {
			singleton_ref(network_t).pop_shared_write_socket(fd);
		}
	}
}
Ejemplo n.º 5
0
void context_lua_t::on_received(message_t& message)
{
	switch (message_raw_type(message)) {
	case LUA_CTX_INIT:
		lua_ctx_init(message);
		return;
	case CONTEXT_QUERY:
		response_context_query(message);
		break;
	case CONTEXT_REPLY:
		response_context_reply(message);
		break;
	case LUA_CTX_WAIT:
		response_context_wait(message);
		break;
	case LUA_CTX_WAKEUP:
		response_context_wakeup(message);
		break;
	case RESPONSE_TCP_LISTEN:
		response_tcp_listen(message);
		break;
	case RESPONSE_TCP_ACCEPT:
		response_tcp_accept(message);
		break;
	case RESPONSE_TCP_CONNECT:
		response_tcp_connect(message);
		break;
	case RESPONSE_TCP_READ:
		response_tcp_read(message);
		break;
	case RESPONSE_TCP_WRITE:
		response_tcp_write(message);
		break;
	case RESPONSE_HANDLE_CLOSE:
		response_handle_close(message);
		break;
	case RESPONSE_TCP_CLOSING:
		response_tcp_closing(message);
		break;
	case RESPONSE_TIMEOUT:
		response_timeout(message);
		break;
	case SYSTEM_CTX_DESTROY:
		singleton_ref(node_lua_t).context_destroy(this, message.m_source, message_string(message));
		return;
	default:
		break;
	}
	if (!is_active()) {
		singleton_ref(node_lua_t).context_destroy(this, m_handle, "lua context exit normally");
	}
}
Ejemplo n.º 6
0
void uv_udp_handle_t::open(request_udp_open_t& request)
{
	uv_udp_t* server = (uv_udp_t*)m_handle;
	if ((!request.m_ipv6 ? uv_udp_bind(server, uv_ip4_addr(REQUEST_SPARE_PTR(request), request.m_port), 0) == 0 : uv_udp_bind6(server, uv_ip6_addr(REQUEST_SPARE_PTR(request), request.m_port), 0) == 0)) {
		m_udp_sock = uv_udp_fd((uv_udp_t*)server);
		if (!singleton_ref(node_lua_t).context_send(request.m_source, 0, request.m_session, RESPONSE_UDP_OPEN, (void*)this)) {
			uv_close((uv_handle_t*)server, on_closed);
		}
	} else {
		singleton_ref(node_lua_t).context_send(request.m_source, 0, request.m_session, RESPONSE_UDP_OPEN, singleton_ref(network_t).last_error());
		uv_close((uv_handle_t*)server, on_closed);
	}
}
Ejemplo n.º 7
0
int32_t context_lua_t::context_destroy(lua_State *L)
{
	int32_t type = lua_type(L, 1);
	uint32_t src_handle = lua_get_context_handle(L);	
	if (type == LUA_TNIL || type == LUA_TSTRING) { //kill self
		singleton_ref(node_lua_t).context_destroy(src_handle, src_handle, lua_tostring(L, 1));
		return 0;
	}
	int32_t handle = luaL_checkunsigned(L, 1);
	if (handle > 0) {
		singleton_ref(node_lua_t).context_destroy(handle, src_handle, lua_tostring(L, 2));
	}
	return 0;
}
Ejemplo n.º 8
0
int32_t uv_udp_handle_t::write_handle(request_udp_write_t& request)
{
	int result;
	uv_buf_t uv_buf;
	write_uv_request_t* uv_request = get_write_cached_request();
	uv_request->m_source = request.m_source;
	uv_request->m_session = request.m_session;
	uv_request->m_length = request.m_length;
	if (request.m_length > 0) {
		uv_request->m_string = request.m_string;
		uv_buf.len = request.m_length;
		uv_buf.base = (char*)request.m_string;
	} else {
		uv_request->m_buffer = request.m_buffer;
		uv_buf.len = buffer_data_length(request.m_buffer);
		uv_buf.base = buffer_data_ptr(request.m_buffer);
	}
	if (!request.m_ipv6) {
		result = uv_udp_send(&uv_request->m_write_req, (uv_udp_t*)m_handle, &uv_buf, 1, uv_ip4_addr(REQUEST_SPARE_PTR(request), request.m_port), on_write);
	} else {
		result = uv_udp_send6(&uv_request->m_write_req, (uv_udp_t*)m_handle, &uv_buf, 1, uv_ip6_addr(REQUEST_SPARE_PTR(request), request.m_port), on_write);
	}
	if (result == 0) return UV_OK;
	put_write_cached_request(uv_request);
	return singleton_ref(network_t).last_error(); /* write error occurs */
}
Ejemplo n.º 9
0
int32_t context_lua_t::context_wait(lua_State *L)
{
	context_lua_t* lctx = (context_lua_t*)lua_get_context(L);
	uint32_t handle = luaL_checkunsigned(L, 1);
	if (handle == 0) {
		luaL_error(L, "invalid context handle to wait");
		return 0;
	}
	if (handle == lctx->get_handle()) {
		luaL_error(L, "can't wait self to die away");
		return 0;
	}
	int32_t top = lua_gettop(L);
	uint64_t timeout = 0;
	int32_t callback = 0;
	int32_t session;
	if (top >= 2) {
		if (lua_isnil(L, 2)) {
			lctx->m_context_wait_sessions.free_nonblocking_callback(handle, L);
			return 0;
		}
		if (lua_isfunction(L, 2)) {
			callback = 2;
		} else {
			timeout = 1000 * luaL_checknumber(L, 2);
			if (top >= 3) {
				luaL_checktype(L, 3, LUA_TFUNCTION);
				callback = 3;
			}
		}
	}
	if (callback > 0) { //nonblocking
		lua_settop(L, callback);
		if (singleton_ref(node_lua_t).context_send(handle, lctx->get_handle(), LUA_REFNIL, LUA_CTX_WAIT, (int64_t)handle)) {
			lctx->m_context_wait_sessions.make_nonblocking_callback(handle, L, callback - 1, common_callback_adjust, &session);
			if (timeout > 0) {
				context_lua_t::lua_ref_timer(L, session, timeout, 0, false, (void*)handle, context_wait_timeout);
			}
		} else {
			singleton_ref(node_lua_t).context_send(lctx, handle, LUA_REFNIL, LUA_CTX_WAKEUP, UV_OK);
		}
		return 0;
	}
	return lctx->lua_yield_send(L, handle, context_wait_yield_finalize, NULL, context_wait_yield_continue, timeout);
}
Ejemplo n.º 10
0
void context_lua_t::response_context_query(message_t& response)
{
	if (response.m_source == 0) return;
	if (!m_context_recv_sessions.wakeup_once(response.m_source, this, response) && !m_context_recv_sessions.wakeup_once(0, this, response)) {
		if (response.m_session != LUA_REFNIL) {
			singleton_ref(node_lua_t).context_send(response.m_source, m_handle, response.m_session, CONTEXT_REPLY, NL_ENOREPLY);
		}
	}
}
Ejemplo n.º 11
0
bool context_lua_t::deinit(const char *arg)
{
	for (std::set<uint32_t>::iterator it = m_context_wait_handles.begin(); it != m_context_wait_handles.end(); ++it) {
		singleton_ref(node_lua_t).context_send(*it, m_handle, LUA_REFNIL, LUA_CTX_WAKEUP, UV_OK);
	}
	m_context_wait_handles.clear();
	if (m_lstate) {
		lua_close(m_lstate);
		m_lstate = NULL;
	}
	printf("[alert] context:0x%08x deinit: %s\n", m_handle, arg);	/* to be implemented : put reason to another context and output it */
	return true;
}
Ejemplo n.º 12
0
void uv_udp_handle_t::on_write(uv_udp_send_t* req, int status)
{
	write_uv_request_t *uv_request = (write_uv_request_t*)req->data;
	uv_udp_handle_t *socket_handle = (uv_udp_handle_t*)(req->handle->data);
	if (uv_request->m_length > 0) {
		nl_free((void*)uv_request->m_string);
	} else {
		buffer_release(uv_request->m_buffer);
	}
	if (uv_request->m_session != LUA_REFNIL) {
		singleton_ref(node_lua_t).context_send(uv_request->m_source, 0, uv_request->m_session, RESPONSE_UDP_WRITE, status == 0 ? UV_OK : singleton_ref(network_t).last_error());
	}
	socket_handle->put_write_cached_request(uv_request);
}
Ejemplo n.º 13
0
void context_lua_t::on_dropped(message_t& message)
{
	switch (message_raw_type(message)) {
	case RESPONSE_TCP_LISTEN:
	case RESPONSE_TCP_ACCEPT:
	case RESPONSE_TCP_CONNECT:
		if (message_is_userdata(message)) {
			uv_handle_base_t* handle = (uv_handle_base_t*)message_userdata(message);
			lua_handle_base_t::close_uv_handle(handle);
		}
		break;
	case CONTEXT_QUERY:
		if (message.m_source != 0 && message.m_session != LUA_REFNIL) {
			singleton_ref(node_lua_t).context_send(message.m_source, m_handle, message.m_session, CONTEXT_REPLY, NL_ENOREPLY);
		}
		return;
	case LUA_CTX_WAIT:
		singleton_ref(node_lua_t).context_send(message.m_source, (uint32_t)message_integer(message), LUA_REFNIL, LUA_CTX_WAKEUP, UV_OK);
		return;
	default:
		break;
	}
}
Ejemplo n.º 14
0
void uv_udp_handle_t::on_read(uv_udp_t* handle, ssize_t nread, uv_buf_t buf, struct sockaddr* addr, unsigned flags)
{
	/* udp max datagram read pack size: SHARED_READ_BUFFER_SIZE(64 * 1024) */
	if (nread == 0) {
		return;
	}
	uv_udp_handle_t* udp_handle = (uv_udp_handle_t*)(handle->data);
	if (nread == -1) {
		singleton_ref(node_lua_t).context_send(udp_handle->m_source, 0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, singleton_ref(network_t).last_error());
		return;
	}
	buffer_t buffer = buffer_new(nread, buf.base, nread);
	char* host = (char*)nl_malloc(64);
	uint16_t port = 0;
	bool ipv6 = false;
	*host = '\0';
	sockaddr_host(addr, host, 64, &ipv6, &port);
	message_array_t* array = message_array_create(4);
	array->m_array[0] = message_t(0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, buffer);
	array->m_array[1] = message_t(0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, host);
	array->m_array[2] = message_t(0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, (int64_t)port);
	array->m_array[3] = message_t(0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, ipv6);
	singleton_ref(node_lua_t).context_send_array_release(udp_handle->m_source, 0, udp_handle->m_lua_ref, RESPONSE_UDP_READ, array);
}
Ejemplo n.º 15
0
void context_lua_t::lua_ctx_init(message_t& message)
{
	int32_t argc = (int32_t)message_integer(message);
	int32_t envc = lua_gettop(m_lstate) - argc;
	const char *file = lua_tostring(m_lstate, 1);
	if (luaL_loadfile(m_lstate, file) == LUA_OK) {
		lua_State *co;
		lua_init(m_lstate);
		lua_insert(m_lstate, -envc - 1);
		lua_init_env(m_lstate, envc);
		co = lua_new_root_coro(m_lstate);
		lua_pushlightuserdata(m_lstate, NULL);
		lua_pushcclosure(m_lstate, lua_ref_callback_entry, argc + 1); /* make the c closure callback */
		lua_xmove(m_lstate, co, 1);  /* move top c closure to co */
		lua_pop(m_lstate, 1);		 /* pop the file name on top */
		resume_coroutine(co, 0);
		if (!is_active()) {
			singleton_ref(node_lua_t).context_destroy(this, m_handle, "lua context exit normally");
		}
		return;
	}
	const char *error = lua_tostring(m_lstate, -1);
	singleton_ref(node_lua_t).context_destroy(this, m_handle, "fail to initialize lua context %s, %s", file, error);
}
Ejemplo n.º 16
0
int32_t context_lua_t::context_wait_yield_finalize(lua_State *root_coro, lua_State *main_coro, void *userdata, uint32_t destination)
{
	if (root_coro != NULL) {
		context_lua_t* lctx = context_lua_t::lua_get_context(root_coro);
		if (singleton_ref(node_lua_t).context_send(destination, lctx->get_handle(), LUA_REFNIL, LUA_CTX_WAIT, (int64_t)destination)) {
			int32_t session = lctx->m_context_wait_sessions.push_blocking(destination, root_coro);
			int64_t timeout = lctx->get_yielding_timeout();
			if (timeout > 0) {
				context_lua_t::lua_ref_timer(main_coro, session, timeout, 0, false, (void*)destination, context_wait_timeout);
			}
			return UV_OK;
		} else {
			return NL_ENOCONTEXT;
		}
	}
	return UV_OK;
}
Ejemplo n.º 17
0
int32_t context_lua_t::context_reply(lua_State *L)
{
	uint32_t handle = luaL_checkunsigned(L, 1);
	int32_t session = luaL_checkinteger(L, 2);
	int32_t ret = context_send(L, 3, handle, session, CONTEXT_REPLY);
	if (ret == UV_OK) {
		lua_pushboolean(L, 1);
		return 1;
	}
	if (ret == NL_ETRANSTYPE) {
		context_t* ctx = lua_get_context(L);
		singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, CONTEXT_REPLY, NL_ETRANSTYPE);
		luaL_argerror(L, 3, common_strerror(NL_ETRANSTYPE));
		return 0;
	}
	lua_pushboolean(L, 0);
	lua_pushinteger(L, NL_ENOCONTEXT);
	return 2;
}
Ejemplo n.º 18
0
bool context_lua_t::init(int32_t argc, char* argv[], char* env[])
{
	m_lstate = luaL_newstateex(this);
	if (argc <= 0) {
		printf("[error] context:0x%08x init failed: lua file is needed to initialize lua context\n", m_handle);			/* to be implemented : put reason to another context and output it */
		return false;
	}
	int32_t envc = 2;
	if (argc > MAX_CTX_ARGC || !lua_checkstack(m_lstate, argc + envc)) {
		printf("[error] context:0x%08x init failed: too many arguments to initialize lua context %s\n", m_handle, argv[0]); /* to be implemented : put reason to another context and output it */
		return false;
	}
	int32_t total_length = 0;
	int32_t lengths[MAX_CTX_ARGC];
	for (int32_t i = 0; i < argc; ++i) {
		lengths[i] = strlen(argv[i]);
		lua_pushlstring(m_lstate, argv[i], lengths[i]);
		total_length += lengths[i] + 1;
	}
	char** envp = env;
	char* lua_path = NULL;
	char* lua_cpath = NULL;
	while (*envp) {
		if (strncmp(*envp, "LUA_PATH=", 9) == 0) {
			lua_path = *envp + 9;
		} else if (strncmp(*envp, "LUA_CPATH=", 10) == 0) {
			lua_cpath = *envp + 10;
		}
		++envp;
	}
	lua_pushstring(m_lstate, lua_path);
	lua_pushstring(m_lstate, lua_cpath);
	char* args = (char*)nl_calloc(total_length, 1);
	char* argp = args;
	for (int32_t i = 0; i < argc; ++i) {
		memcpy(argp, argv[i], lengths[i]);
		argp += lengths[i];
		*argp++ = (i != argc - 1) ? ' ' : '\0';
	}
	printf("[alert] context:0x%08x init: %s\n", m_handle, args); /* to be implemented : put reason to another context and output it */
	nl_free(args);
	return singleton_ref(node_lua_t).context_send(this, m_handle, 0, LUA_CTX_INIT, (int64_t)argc);
}
Ejemplo n.º 19
0
lua_timer_handle_t* lua_timer_handle_t::create_timer(lua_State* L, int32_t session, uint64_t timeout, uint64_t repeat, bool is_cancel, void *userdata, timeout_callback_t callback)
{
	lua_checkstack(L, 3);
	uv_timer_handle_t* uv_timer = new uv_timer_handle_t(context_lua_t::lua_get_context_handle(L));
	lua_timer_handle_t* lua_timer = new(lua_newuserdata(L, sizeof(lua_timer_handle_t)))lua_timer_handle_t(uv_timer, L, session, repeat > 0, is_cancel, userdata, callback);
	if (luaL_newmetatable(L, TIMER_METATABLE)) { /* create new metatable */
		lua_pushcfunction(L, lua_timer_handle_t::release);
		lua_setfield(L, -2, "__gc");
	}
	lua_setmetatable(L, -2);
	request_t request;
	request.m_type = REQUEST_TIMER_START;
	request.m_length = REQUEST_SIZE(request_timer_start_t, 0);
	request.m_timer_start.m_timer_handle = uv_timer;
	request.m_timer_start.m_timeout = timeout;
	request.m_timer_start.m_repeat = repeat;
	singleton_ref(network_t).send_request(request);
	return lua_timer;
}
Ejemplo n.º 20
0
int32_t context_lua_t::context_send(lua_State *L, int32_t idx, uint32_t handle, int32_t session, uint32_t msg_type)
{
	bool ret = false;
	nil_t nil;
	buffer_t* buffer;
	context_t* ctx = lua_get_context(L);
	switch (lua_type(L, idx)) {
	case LUA_TNUMBER:
		if (lua_isinteger(L, idx)) {
			ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, (int64_t)lua_tointeger(L, idx));
		} else {
			ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, (double)lua_tonumber(L, idx));
		}
		break;
	case LUA_TSTRING:
		ret = singleton_ref(node_lua_t).context_send_string_safe(handle, ctx->get_handle(), session, msg_type, lua_tostring(L, idx));
		break;
	case LUA_TBOOLEAN:
		ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, (bool)lua_toboolean(L, idx));
		break;
	case LUA_TNIL:
		ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, nil);
		break;
	case LUA_TUSERDATA:
		buffer = (buffer_t*)luaL_testudata(L, idx, BUFFER_METATABLE);
		if (buffer) {
			ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, *buffer);
			break;
		} else {
			return NL_ETRANSTYPE;
		}
		//to be fix : bson, array
	case LUA_TLIGHTUSERDATA:
		ret = singleton_ref(node_lua_t).context_send(handle, ctx->get_handle(), session, msg_type, (void*)lua_touserdata(L, idx));
		break;
	default:
		return NL_ETRANSTYPE;
	}
	return ret ? UV_OK : NL_ENOCONTEXT;
}
Ejemplo n.º 21
0
int32_t context_lua_t::context_create(lua_State *L)
{
	int32_t argc = lua_gettop(L);
	if (argc <= 0) {
		luaL_error(L, "lua file is needed to initialize lua context");
	}
	if (argc > MAX_CTX_ARGC) {
		luaL_error(L, "too many arguments to initialize lua context");
	}
	char* argv[MAX_CTX_ARGC];
	char* env[16] = { NULL };
	lua_load_env(L, env);
	for (int32_t i = 0; i < argc; ++i) {
		argv[i] = (char*)luaL_checkstring(L, i + 1);
	}
	uint32_t parent = lua_get_context_handle(L);
	uint32_t handle = singleton_ref(node_lua_t).context_create<context_lua_t>(parent, argc, argv, env);
	lua_free_env(L, env);
	if (handle > 0) {
		lua_pushinteger(L, handle);
		return 1;
	}
	return 0;
}
Ejemplo n.º 22
0
uv_udp_handle_t::~uv_udp_handle_t()
{
	clear_write_cached_requests();
	singleton_ref(network_t).pop_shared_write_socket(SOCKET_MAKE_FD(m_lua_ref, m_source));
}
Ejemplo n.º 23
0
void worker_mgr_t::worker_entry(void* arg)
{
	singleton_ref(worker_mgr_t).worker_process((int64_t)arg);
}
Ejemplo n.º 24
0
uv_buf_t uv_udp_handle_t::on_read_alloc(uv_handle_t* handle, size_t suggested_size)
{
	return singleton_ref(network_t).make_shared_read_buffer();
}