diff --git a/src/logic/scripting/lua/libs/libnetwork.cpp b/src/logic/scripting/lua/libs/libnetwork.cpp index a4cc88ab..378f0cbc 100644 --- a/src/logic/scripting/lua/libs/libnetwork.cpp +++ b/src/logic/scripting/lua/libs/libnetwork.cpp @@ -4,6 +4,7 @@ #include "network/Network.hpp" #include +#include using namespace scripting; @@ -37,8 +38,7 @@ struct NetworkDatagramEventDto { u64id_t client; std::string addr; int port; - const char* buffer; - size_t length; + std::vector buffer; }; struct NetworkEvent { @@ -60,6 +60,12 @@ struct NetworkEvent { }; static std::vector events_queue {}; +static std::mutex events_queue_mutex; + +static void push_event(NetworkEvent&& event) { + std::lock_guard lock(events_queue_mutex); + events_queue.push_back(std::move(event)); +} static std::vector read_headers(lua::State* L, int index) { std::vector headers; @@ -83,7 +89,7 @@ static int perform_get(lua::State* L, network::Network& network, bool binary) { int currentRequestId = request_id; network.get(url, [currentRequestId, binary](std::vector bytes) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( RESPONSE, ResponseEventDto { 200, @@ -93,7 +99,7 @@ static int perform_get(lua::State* L, network::Network& network, bool binary) { } )); }, [currentRequestId](int code) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( RESPONSE, ResponseEventDto { code, @@ -135,7 +141,7 @@ static int l_post(lua::State* L, network::Network& network) { auto buffer = std::make_shared>( reinterpret_cast(bytes.data()), bytes.size() ); - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( RESPONSE, ResponseEventDto { 200, @@ -145,7 +151,7 @@ static int l_post(lua::State* L, network::Network& network) { )); }, [currentRequestId](int code) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( RESPONSE, ResponseEventDto {code, false, currentRequestId, {}} )); }, @@ -280,7 +286,7 @@ static int l_connect_tcp(lua::State* L, network::Network& network) { std::string address = lua::require_string(L, 1); int port = lua::tointeger(L, 2); u64id_t id = network.connectTcp(address, port, [](u64id_t cid) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( CONNECTED_TO_SERVER, ConnectionEventDto {0, cid} )); @@ -291,7 +297,7 @@ static int l_connect_tcp(lua::State* L, network::Network& network) { static int l_open_tcp(lua::State* L, network::Network& network) { int port = lua::tointeger(L, 1); u64id_t id = network.openTcpServer(port, [](u64id_t sid, u64id_t id) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( CLIENT_CONNECTED, ConnectionEventDto {sid, id} )); @@ -303,7 +309,7 @@ static int l_connect_udp(lua::State* L, network::Network& network) { std::string address = lua::require_string(L, 1); int port = lua::tointeger(L, 2); u64id_t id = network.connectUdp(address, port, [](u64id_t cid) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( CONNECTED_TO_SERVER, ConnectionEventDto {0, cid} )); @@ -312,11 +318,11 @@ static int l_connect_udp(lua::State* L, network::Network& network) { const char* buffer, size_t length ) { - events_queue.push_back(NetworkEvent( + push_event(NetworkEvent( DATAGRAM, NetworkDatagramEventDto { ON_CLIENT, 0, cid, - address, port, buffer, length + address, port, std::vector(buffer, buffer + length) } )); }); @@ -331,12 +337,12 @@ static int l_open_udp(lua::State* L, network::Network& network) { int port, const char* buffer, size_t length) { - events_queue.push_back( + push_event( NetworkEvent( DATAGRAM, NetworkDatagramEventDto { ON_SERVER, sid, 0, - addr, port, buffer, length + addr, port, std::vector(buffer, buffer + length) } ) ); @@ -404,16 +410,23 @@ static int l_get_total_download(lua::State* L, network::Network& network) { } static int l_pull_events(lua::State* L, network::Network& network) { - lua::createtable(L, events_queue.size(), 0); + std::vector local_queue; + { + std::lock_guard lock(events_queue_mutex); + local_queue.swap(events_queue); + } - for (size_t i = 0; i < events_queue.size(); i++) { + lua::createtable(L, local_queue.size(), 0); + + for (size_t i = 0; i < local_queue.size(); i++) { lua::createtable(L, 7, 0); - switch (events_queue[i].type) { + const auto& event = local_queue[i]; + switch (event.type) { case CLIENT_CONNECTED: case CONNECTED_TO_SERVER: { - const auto& dto = std::get(events_queue[i].payload); - lua::pushinteger(L, events_queue[i].type); + const auto& dto = std::get(event.payload); + lua::pushinteger(L, event.type); lua::rawseti(L, 1); lua::pushinteger(L, dto.server); @@ -424,8 +437,8 @@ static int l_pull_events(lua::State* L, network::Network& network) { break; } case DATAGRAM: { - const auto& dto = std::get(events_queue[i].payload); - lua::pushinteger(L, events_queue[i].type); + const auto& dto = std::get(event.payload); + lua::pushinteger(L, event.type); lua::rawseti(L, 1); lua::pushinteger(L, dto.server); @@ -443,13 +456,13 @@ static int l_pull_events(lua::State* L, network::Network& network) { lua::pushinteger(L, dto.side); lua::rawseti(L, 6); - lua::create_bytearray(L, dto.buffer, dto.length); + lua::create_bytearray(L, dto.buffer.data(), dto.buffer.size()); lua::rawseti(L, 7); break; } case RESPONSE: { - const auto& dto = std::get(events_queue[i].payload); - lua::pushinteger(L, events_queue[i].type); + const auto& dto = std::get(event.payload); + lua::pushinteger(L, event.type); lua::rawseti(L, 1); lua::pushinteger(L, dto.status); @@ -469,7 +482,6 @@ static int l_pull_events(lua::State* L, network::Network& network) { } lua::rawseti(L, i + 1); } - events_queue.clear(); return 1; } diff --git a/src/network/Network.cpp b/src/network/Network.cpp index b0482258..fe0eb28d 100644 --- a/src/network/Network.cpp +++ b/src/network/Network.cpp @@ -642,19 +642,19 @@ public: ) { SOCKET descriptor = socket(AF_INET, SOCK_DGRAM, 0); if (descriptor == -1) { - throw std::runtime_error("could not create UDP socket"); + throw std::runtime_error("could not create udp socket"); } sockaddr_in serverAddr{}; serverAddr.sin_family = AF_INET; if (inet_pton(AF_INET, address.c_str(), &serverAddr.sin_addr) <= 0) { closesocket(descriptor); - throw std::runtime_error("invalid UDP address: " + address); + throw std::runtime_error("invalid udp address: " + address); } serverAddr.sin_port = htons(port); if (::connect(descriptor, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) { - auto err = handle_socket_error("UDP connect failed"); + auto err = handle_socket_error("udp connect failed"); closesocket(descriptor); throw err; } @@ -810,7 +810,7 @@ public: u64id_t id, Network* network, int port, const ServerDatagramCallback& handler ) { SOCKET descriptor = socket(AF_INET, SOCK_DGRAM, 0); - if (descriptor == -1) throw std::runtime_error("Could not create UDP socket"); + if (descriptor == -1) throw std::runtime_error("could not create udp socket"); sockaddr_in address{}; address.sin_family = AF_INET; @@ -819,7 +819,7 @@ public: if (bind(descriptor, (sockaddr*)&address, sizeof(address)) < 0) { closesocket(descriptor); - throw std::runtime_error("Could not bind UDP port " + std::to_string(port)); + throw std::runtime_error("could not bind udp port " + std::to_string(port)); } auto server = std::make_shared(id, network, descriptor, port);