http tasks can now be cancelled

This commit is contained in:
Andre Leiradella 2016-05-05 15:32:36 -03:00
parent 8a77ac1f04
commit 8be7fd5f0a
4 changed files with 55 additions and 10 deletions

View File

@ -82,8 +82,13 @@ enum task_queue_ctl_state
TASK_QUEUE_CTL_UNSET_THREADED, TASK_QUEUE_CTL_UNSET_THREADED,
TASK_QUEUE_CTL_IS_THREADED TASK_QUEUE_CTL_IS_THREADED,
};
/**
* Signals a task to end without waiting for
* it to complete. */
TASK_QUEUE_CTL_CANCEL,
};
typedef struct retro_task retro_task_t; typedef struct retro_task retro_task_t;
typedef void (*retro_task_callback_t)(void *task_data, typedef void (*retro_task_callback_t)(void *task_data,
@ -148,6 +153,8 @@ void task_queue_push_progress(retro_task_t *task);
bool task_queue_ctl(enum task_queue_ctl_state state, void *data); bool task_queue_ctl(enum task_queue_ctl_state state, void *data);
void task_queue_cancel_task(void *task);
RETRO_END_DECLS RETRO_END_DECLS
#endif #endif

View File

@ -39,6 +39,7 @@ typedef struct
struct retro_task_impl struct retro_task_impl
{ {
void (*push_running)(retro_task_t *); void (*push_running)(retro_task_t *);
void (*cancel)(void *);
void (*reset)(void); void (*reset)(void);
void (*wait)(void); void (*wait)(void);
void (*gather)(void); void (*gather)(void);
@ -167,6 +168,12 @@ static void retro_task_regular_push_running(retro_task_t *task)
task_queue_put(&tasks_running, task); task_queue_put(&tasks_running, task);
} }
static void retro_task_regular_cancel(void *task)
{
retro_task_t *t = task;
t->cancelled = true;
}
static void retro_task_regular_gather(void) static void retro_task_regular_gather(void)
{ {
retro_task_t *task = NULL; retro_task_t *task = NULL;
@ -232,6 +239,7 @@ static bool retro_task_regular_find(retro_task_finder_t func, void *user_data)
static struct retro_task_impl impl_regular = { static struct retro_task_impl impl_regular = {
retro_task_regular_push_running, retro_task_regular_push_running,
retro_task_regular_cancel,
retro_task_regular_reset, retro_task_regular_reset,
retro_task_regular_wait, retro_task_regular_wait,
retro_task_regular_gather, retro_task_regular_gather,
@ -255,6 +263,24 @@ static void retro_task_threaded_push_running(retro_task_t *task)
slock_unlock(running_lock); slock_unlock(running_lock);
} }
static void retro_task_threaded_cancel(void *task)
{
retro_task_t *t;
slock_lock(running_lock);
for (t = tasks_running.front; t; t = t->next)
{
if (t == task)
{
t->cancelled = true;
break;
}
}
slock_unlock(running_lock);
}
static void retro_task_threaded_gather(void) static void retro_task_threaded_gather(void)
{ {
retro_task_t *task = NULL; retro_task_t *task = NULL;
@ -399,6 +425,7 @@ static void retro_task_threaded_deinit(void)
static struct retro_task_impl impl_threaded = { static struct retro_task_impl impl_threaded = {
retro_task_threaded_push_running, retro_task_threaded_push_running,
retro_task_threaded_cancel,
retro_task_threaded_reset, retro_task_threaded_reset,
retro_task_threaded_wait, retro_task_threaded_wait,
retro_task_threaded_gather, retro_task_threaded_gather,
@ -484,6 +511,9 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data)
case TASK_QUEUE_CTL_WAIT: case TASK_QUEUE_CTL_WAIT:
impl_current->wait(); impl_current->wait();
break; break;
case TASK_QUEUE_CTL_CANCEL:
impl_current->cancel(data);
break;
case TASK_QUEUE_CTL_NONE: case TASK_QUEUE_CTL_NONE:
default: default:
break; break;
@ -491,3 +521,8 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data)
return true; return true;
} }
void task_queue_cancel_task(void *task)
{
task_queue_ctl(TASK_QUEUE_CTL_CANCEL, task);
}

View File

@ -127,6 +127,9 @@ static void rarch_task_http_transfer_handler(retro_task_t *task)
http_handle_t *http = (http_handle_t*)task->state; http_handle_t *http = (http_handle_t*)task->state;
http_transfer_data_t *data; http_transfer_data_t *data;
if (task->cancelled)
goto task_finished;
switch (http->status) switch (http->status)
{ {
case HTTP_STATUS_CONNECTION_TRANSFER_PARSE: case HTTP_STATUS_CONNECTION_TRANSFER_PARSE:
@ -148,7 +151,7 @@ static void rarch_task_http_transfer_handler(retro_task_t *task)
break; break;
} }
if (task->cancelled || http->error) if (http->error)
goto task_finished; goto task_finished;
return; return;
@ -251,7 +254,7 @@ static bool rarch_task_http_retriever(retro_task_t *task, void *user_data)
return false; return false;
} }
bool rarch_task_push_http_transfer(const char *url, const char *type, void *rarch_task_push_http_transfer(const char *url, const char *type,
retro_task_callback_t cb, void *user_data) retro_task_callback_t cb, void *user_data)
{ {
char tmp[PATH_MAX_LENGTH]; char tmp[PATH_MAX_LENGTH];
@ -261,7 +264,7 @@ bool rarch_task_push_http_transfer(const char *url, const char *type,
http_handle_t *http = NULL; http_handle_t *http = NULL;
if (string_is_empty(url)) if (string_is_empty(url))
return false; return NULL;
find_data.func = rarch_task_http_finder; find_data.func = rarch_task_http_finder;
find_data.userdata = (void*)url; find_data.userdata = (void*)url;
@ -270,13 +273,13 @@ bool rarch_task_push_http_transfer(const char *url, const char *type,
if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data)) if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data))
{ {
RARCH_LOG("[http] '%s'' is already being downloaded.\n", url); RARCH_LOG("[http] '%s'' is already being downloaded.\n", url);
return false; return NULL;
} }
conn = net_http_connection_new(url); conn = net_http_connection_new(url);
if (!conn) if (!conn)
return false; return NULL;
http = (http_handle_t*)calloc(1, sizeof(*http)); http = (http_handle_t*)calloc(1, sizeof(*http));
@ -310,7 +313,7 @@ bool rarch_task_push_http_transfer(const char *url, const char *type,
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t); task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
return true; return t;
error: error:
if (conn) if (conn)
@ -320,7 +323,7 @@ error:
if (http) if (http)
free(http); free(http);
return false; return NULL;
} }
http_transfer_info_t *http_task_get_transfer_list() http_transfer_info_t *http_task_get_transfer_list()

View File

@ -41,7 +41,7 @@ typedef struct http_transfer_info
struct http_transfer_info *next; struct http_transfer_info *next;
} http_transfer_info_t; } http_transfer_info_t;
bool rarch_task_push_http_transfer(const char *url, const char *type, void *rarch_task_push_http_transfer(const char *url, const char *type,
retro_task_callback_t cb, void *userdata); retro_task_callback_t cb, void *userdata);
http_transfer_info_t *http_task_get_transfer_list(); http_transfer_info_t *http_task_get_transfer_list();