(Netplay/LAN Discovery) Task refactor (#14070)

This commit is contained in:
Cthulhu-throwaway 2022-06-18 22:41:04 -03:00 committed by GitHub
parent 0008691aa0
commit dabd9cb996
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 57 deletions

View File

@ -6088,16 +6088,16 @@ static int action_ok_push_netplay_refresh_rooms(const char *path,
}
#ifdef HAVE_NETPLAYDISCOVERY
static void netplay_refresh_lan_cb(retro_task_t *task, void *task_data,
void *user_data, const char *error)
static void netplay_refresh_lan_cb(const void *data)
{
int i;
const char *path = NULL;
const char *label = NULL;
unsigned menu_type = 0;
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
struct netplay_host_list *hosts = NULL;
bool refresh = false;
const struct netplay_host_list *hosts =
(const struct netplay_host_list*)data;
net_driver_state_t *net_st = networking_state_get_ptr();
free(net_st->room_list);
@ -6109,11 +6109,8 @@ static void netplay_refresh_lan_cb(retro_task_t *task, void *task_data,
/* Don't push the results if we left the netplay menu */
if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
goto deinit;
return;
if (!netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts))
goto done;
if (!hosts || !hosts->size)
goto done;
@ -6154,15 +6151,12 @@ static void netplay_refresh_lan_cb(retro_task_t *task, void *task_data,
done:
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
deinit:
deinit_netplay_discovery();
}
static int action_ok_push_netplay_refresh_lan(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
task_push_netplay_lan_scan(netplay_refresh_lan_cb);
task_push_netplay_lan_scan(netplay_refresh_lan_cb, 800);
return 0;
}

View File

@ -240,7 +240,7 @@ bool init_netplay_discovery(void)
net_st->lan_ad_client_fd = fd;
ret = socket_bind(fd, addr);
ret = socket_bind(fd, addr) && socket_nonblock(fd);
}
if (!ret)
{
@ -305,6 +305,8 @@ static bool netplay_lan_ad_client_query(void)
static bool netplay_lan_ad_client_response(void)
{
size_t count;
ssize_t ret;
char address[16];
struct ad_packet ad_packet_buffer;
struct netplay_host *host;
@ -312,21 +314,19 @@ static bool netplay_lan_ad_client_response(void)
net_driver_state_t *net_st = &networking_driver_st;
/* Check for any ad queries */
for (;;)
for (count = 0;;)
{
bool has_data = true;
struct sockaddr_storage their_addr = {0};
socklen_t addr_size = sizeof(their_addr);
if (!socket_wait(net_st->lan_ad_client_fd, &has_data, NULL, 500) ||
!has_data)
break;
ret = recvfrom(net_st->lan_ad_client_fd,
(char*)&ad_packet_buffer, sizeof(ad_packet_buffer), 0,
(struct sockaddr*)&their_addr, &addr_size);
if (ret < 0)
return isagain((int)ret) && count > 0;
/* Somebody queried, so check that it's valid */
if (recvfrom(net_st->lan_ad_client_fd,
(char*)&ad_packet_buffer, sizeof(ad_packet_buffer), 0,
(struct sockaddr*)&their_addr, &addr_size) !=
sizeof(ad_packet_buffer))
if (ret != sizeof(ad_packet_buffer))
continue;
/* Make sure it's a valid response */
@ -430,9 +430,9 @@ static bool netplay_lan_ad_client_response(void)
has_password = ntohl(ad_packet_buffer.has_password);
host->has_password = (has_password & 1) ? true : false;
host->has_spectate_password = (has_password & 2) ? true : false;
}
return true;
count++;
}
}
/** Discovery control */
@ -441,19 +441,14 @@ bool netplay_discovery_driver_ctl(
{
net_driver_state_t *net_st = &networking_driver_st;
if (net_st->lan_ad_client_fd < 0)
return false;
switch (state)
{
case RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY:
return netplay_lan_ad_client_query();
return net_st->lan_ad_client_fd >= 0 && netplay_lan_ad_client_query();
case RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES:
if (!netplay_lan_ad_client_response())
return false;
*(struct netplay_host_list**)data = &net_st->discovered_hosts;
break;
return net_st->lan_ad_client_fd >= 0 &&
netplay_lan_ad_client_response();
case RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES:
net_st->discovered_hosts.size = 0;
@ -473,7 +468,8 @@ static bool init_lan_ad_server_socket(void)
net_driver_state_t *net_st = &networking_driver_st;
int fd = socket_init((void**)&addr, RARCH_DEFAULT_PORT,
NULL, SOCKET_TYPE_DATAGRAM);
bool ret = fd >= 0 && addr && socket_bind(fd, addr);
bool ret = fd >= 0 && addr &&
socket_bind(fd, addr) && socket_nonblock(fd);
if (ret)
{

View File

@ -1,6 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2016-2017 - Jean-André Santoni
* Copyright (C) 2016-2019 - Andrés Suárez
* Copyright (C) 2021-2022 - Roberto V. Rampim
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -14,50 +15,106 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <lists/file_list.h>
#include <string/stdstring.h>
#include "../paths.h"
#include <features/features_cpu.h>
#include "task_file_transfer.h"
#include "tasks_internal.h"
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "../verbosity.h"
#ifdef HAVE_NETWORKING
#include "../network/netplay/netplay.h"
#endif
#ifdef HAVE_NETPLAYDISCOVERY
#include "../network/netplay/netplay.h"
struct netplay_lan_scan_data
{
retro_time_t timeout;
void (*cb)(const void*);
bool query;
bool busy;
};
static void task_netplay_lan_scan_handler(retro_task_t *task)
{
if (init_netplay_discovery())
struct netplay_lan_scan_data *data =
(struct netplay_lan_scan_data*)task->task_data;
if (data->query)
{
netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES, NULL);
netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY, NULL);
if (!init_netplay_discovery())
goto finished;
if (!netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY, NULL))
goto finished;
data->timeout += cpu_features_get_time_usec();
data->query = false;
}
else
{
if (!netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, NULL))
{
if (cpu_features_get_time_usec() >= data->timeout)
goto finished;
}
}
return;
finished:
deinit_netplay_discovery();
task_set_progress(task, 100);
task_set_finished(task, true);
}
bool task_push_netplay_lan_scan(retro_task_callback_t cb)
static void task_netplay_lan_scan_callback(retro_task_t *task,
void *task_data, void *user_data, const char *error)
{
retro_task_t *task = task_init();
struct netplay_lan_scan_data *data =
(struct netplay_lan_scan_data*)task_data;
net_driver_state_t *net_st = networking_state_get_ptr();
data->cb(&net_st->discovered_hosts);
data->busy = false;
}
bool task_push_netplay_lan_scan(void (*cb)(const void*), unsigned timeout)
{
static struct netplay_lan_scan_data data = {0};
retro_task_t *task;
/* Do not run more than one LAN scan task at a time. */
if (data.busy)
return false;
task = task_init();
if (!task)
return false;
task->type = TASK_TYPE_BLOCKING;
data.busy = true;
data.query = true;
data.timeout = (retro_time_t)timeout * 1000;
data.cb = cb;
task->handler = task_netplay_lan_scan_handler;
task->callback = cb;
task->callback = task_netplay_lan_scan_callback;
task->task_data = &data;
task_queue_push(task);
return true;
}
#else
bool task_push_netplay_lan_scan(void (*cb)(const void*), unsigned timeout)
{
return false;
}
#endif

View File

@ -87,7 +87,7 @@ bool task_push_wifi_disable(retro_task_callback_t cb);
bool task_push_wifi_disconnect(retro_task_callback_t cb);
bool task_push_wifi_connect(retro_task_callback_t cb, void*);
bool task_push_netplay_lan_scan(retro_task_callback_t cb);
bool task_push_netplay_lan_scan(void (*cb)(const void*), unsigned timeout);
bool task_push_netplay_crc_scan(uint32_t crc, char* name,
const char *hostname, const char *corename, const char* subsystem);