mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
(task_http) Disallow same-file concurrent downloads
This commit is contained in:
parent
4e0a4150b5
commit
f84bea4302
@ -36,6 +36,8 @@ bool net_http_connection_done(struct http_connection_t *conn);
|
||||
|
||||
void net_http_connection_free(struct http_connection_t *conn);
|
||||
|
||||
const char *net_http_connection_url(struct http_connection_t *conn);
|
||||
|
||||
struct http_t *net_http_new(struct http_connection_t *conn);
|
||||
|
||||
/* You can use this to call net_http_update
|
||||
|
@ -260,6 +260,11 @@ void net_http_connection_free(struct http_connection_t *conn)
|
||||
free(conn);
|
||||
}
|
||||
|
||||
const char *net_http_connection_url(struct http_connection_t *conn)
|
||||
{
|
||||
return conn->urlcopy;
|
||||
}
|
||||
|
||||
struct http_t *net_http_new(struct http_connection_t *conn)
|
||||
{
|
||||
bool error;
|
||||
|
@ -193,6 +193,18 @@ task_finished:
|
||||
free(http);
|
||||
}
|
||||
|
||||
static bool rarch_task_http_finder(rarch_task_t *task, void *user_data)
|
||||
{
|
||||
http_handle_t *http = (http_handle_t*)task->state;
|
||||
const char *handle_url;
|
||||
if (task->handler != rarch_task_http_transfer_handler)
|
||||
return false;
|
||||
|
||||
handle_url = net_http_connection_url(http->connection.handle);
|
||||
|
||||
return strcmp(handle_url, (const char*)user_data) == 0;
|
||||
}
|
||||
|
||||
bool rarch_task_push_http_transfer(const char *url, const char *type, rarch_task_callback_t cb, void *user_data)
|
||||
{
|
||||
rarch_task_t *t;
|
||||
@ -203,6 +215,13 @@ bool rarch_task_push_http_transfer(const char *url, const char *type, rarch_task
|
||||
if (!url || !*url)
|
||||
return false;
|
||||
|
||||
/* Concurrent download of the same file is not allowed */
|
||||
if (rarch_task_find(rarch_task_http_finder, (void*)url))
|
||||
{
|
||||
RARCH_LOG("%s is already being downloaded.\n", url);
|
||||
return false;
|
||||
}
|
||||
|
||||
conn = net_http_connection_new(url);
|
||||
|
||||
if (!conn)
|
||||
|
@ -17,9 +17,10 @@ typedef struct {
|
||||
|
||||
struct rarch_task_impl {
|
||||
void (*push_running)(rarch_task_t *);
|
||||
void (*cancel)(void);
|
||||
void (*reset)(void);
|
||||
void (*wait)(void);
|
||||
void (*gather)(void);
|
||||
bool (*find)(rarch_task_finder_t, void*);
|
||||
void (*init)(void);
|
||||
void (*deinit)(void);
|
||||
};
|
||||
@ -132,7 +133,7 @@ static void regular_wait(void)
|
||||
regular_gather();
|
||||
}
|
||||
|
||||
static void regular_cancel()
|
||||
static void regular_reset()
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
@ -148,11 +149,25 @@ static void regular_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static bool regular_find(rarch_task_finder_t func, void *user_data)
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
{
|
||||
if (func(task, user_data))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct rarch_task_impl impl_regular = {
|
||||
regular_push_running,
|
||||
regular_cancel,
|
||||
regular_reset,
|
||||
regular_wait,
|
||||
regular_gather,
|
||||
regular_find,
|
||||
regular_init,
|
||||
regular_deinit
|
||||
};
|
||||
@ -199,7 +214,7 @@ static void threaded_wait(void)
|
||||
} while (wait);
|
||||
}
|
||||
|
||||
static void threaded_cancel(void)
|
||||
static void threaded_reset(void)
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
@ -262,6 +277,21 @@ static void threaded_worker(void *userdata)
|
||||
slock_unlock(running_lock);
|
||||
}
|
||||
|
||||
static bool threaded_find(rarch_task_finder_t func, void *user_data)
|
||||
{
|
||||
rarch_task_t *task;
|
||||
|
||||
slock_lock(running_lock);
|
||||
for (task = tasks_running.front; task; task = task->next)
|
||||
{
|
||||
if (func(task, user_data))
|
||||
return true;
|
||||
}
|
||||
slock_unlock(running_lock);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void threaded_init(void)
|
||||
{
|
||||
running_lock = slock_new();
|
||||
@ -296,9 +326,10 @@ static void threaded_deinit(void)
|
||||
|
||||
static struct rarch_task_impl impl_threaded = {
|
||||
threaded_push_running,
|
||||
threaded_cancel,
|
||||
threaded_reset,
|
||||
threaded_wait,
|
||||
threaded_gather,
|
||||
threaded_find,
|
||||
threaded_init,
|
||||
threaded_deinit
|
||||
};
|
||||
@ -358,5 +389,10 @@ void rarch_task_wait(void)
|
||||
|
||||
void rarch_task_reset(void)
|
||||
{
|
||||
impl_current->cancel();
|
||||
impl_current->reset();
|
||||
}
|
||||
|
||||
bool rarch_task_find(rarch_task_finder_t func, void *user_data)
|
||||
{
|
||||
return impl_current->find(func, user_data);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ extern "C" {
|
||||
typedef struct rarch_task rarch_task_t;
|
||||
typedef void (*rarch_task_callback_t)(void *task_data, void *user_data, const char *error);
|
||||
typedef void (*rarch_task_handler_t)(rarch_task_t *task);
|
||||
typedef bool (*rarch_task_finder_t)(rarch_task_t *task, void *user_data);
|
||||
|
||||
struct rarch_task {
|
||||
rarch_task_handler_t handler;
|
||||
@ -107,6 +108,15 @@ void rarch_task_reset(void);
|
||||
*/
|
||||
void rarch_task_wait(void);
|
||||
|
||||
/**
|
||||
* @brief Calls func for every running task until it returns true.
|
||||
*
|
||||
* @param func
|
||||
* @param user_data
|
||||
* @return a task or NULL if not found.
|
||||
*/
|
||||
bool rarch_task_find(rarch_task_finder_t func, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Pushes a task
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user