mirror of
https://github.com/libretro/RetroArch
synced 2025-04-10 06:44:27 +00:00
Rewrite task_queue
This commit is contained in:
parent
1345e97f8c
commit
80d9d1f143
@ -3500,6 +3500,6 @@ bool cheevos_load(const void *data)
|
||||
task->progress = 0;
|
||||
task->title = NULL;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
return true;
|
||||
}
|
||||
|
@ -48,7 +48,9 @@ static void emscripten_mainloop(void)
|
||||
|
||||
if (ret == 1 && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
|
||||
task_queue_check();
|
||||
|
||||
if (ret != -1)
|
||||
return;
|
||||
|
||||
|
@ -384,7 +384,9 @@ static void android_app_entry(void *data)
|
||||
|
||||
if (ret == 1 && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
|
||||
task_queue_check();
|
||||
|
||||
if (ret == -1)
|
||||
break;
|
||||
}while(1);
|
||||
|
@ -450,7 +450,7 @@ int main(int argc, char **argv)
|
||||
if (ret == 1 && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_WAIT, NULL);
|
||||
task_queue_wait();
|
||||
|
||||
if (ret == -1)
|
||||
break;
|
||||
|
@ -130,7 +130,9 @@ int rarch_main(int argc, char *argv[], void *data)
|
||||
|
||||
if (ret == 1 && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
|
||||
task_queue_check();
|
||||
|
||||
if (ret == -1)
|
||||
break;
|
||||
}while(1);
|
||||
|
@ -526,14 +526,14 @@ static bool ctr_frame(void* data, const void* frame,
|
||||
}
|
||||
frames++;
|
||||
#ifndef HAVE_THREADS
|
||||
if(task_queue_ctl(TASK_QUEUE_CTL_FIND, &ctr_tasks_finder_data))
|
||||
if(task_queue_find(&ctr_tasks_finder_data))
|
||||
{
|
||||
#if 0
|
||||
ctr->vsync_event_pending = true;
|
||||
#endif
|
||||
while(ctr->vsync_event_pending)
|
||||
{
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
task_queue_check();
|
||||
svcSleepThread(0);
|
||||
#if 0
|
||||
aptMainLoop();
|
||||
|
@ -43,53 +43,6 @@ enum task_type
|
||||
};
|
||||
|
||||
|
||||
enum task_queue_ctl_state
|
||||
{
|
||||
TASK_QUEUE_CTL_NONE = 0,
|
||||
|
||||
/**
|
||||
* Calls func for every running task
|
||||
* until it returns true.
|
||||
* Returns a task or NULL if not found.
|
||||
*/
|
||||
TASK_QUEUE_CTL_FIND,
|
||||
|
||||
/**
|
||||
* Calls func for every running task when handler
|
||||
* parameter matches task handler, allowing the
|
||||
* list parameter to be filled with user-defined
|
||||
* data.
|
||||
*/
|
||||
TASK_QUEUE_CTL_RETRIEVE,
|
||||
|
||||
/* Blocks until all tasks have finished.
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_WAIT,
|
||||
|
||||
/* Checks for finished tasks
|
||||
* Takes the finished tasks, if any,
|
||||
* and runs their callbacks.
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_CHECK,
|
||||
|
||||
/* Pushes a task
|
||||
* The task will start as soon as possible. */
|
||||
TASK_QUEUE_CTL_PUSH,
|
||||
|
||||
/* Sends a signal to terminate all the tasks.
|
||||
*
|
||||
* This won't terminate the tasks immediately.
|
||||
* They will finish as soon as possible.
|
||||
*
|
||||
* This must only be called from the main thread. */
|
||||
TASK_QUEUE_CTL_RESET,
|
||||
|
||||
/**
|
||||
* Signals a task to end without waiting for
|
||||
* it to complete. */
|
||||
TASK_QUEUE_CTL_CANCEL
|
||||
};
|
||||
|
||||
typedef struct retro_task retro_task_t;
|
||||
typedef void (*retro_task_callback_t)(void *task_data,
|
||||
void *user_data, const char *error);
|
||||
@ -177,8 +130,6 @@ typedef struct task_retriever_data
|
||||
task_retriever_info_t *list;
|
||||
} task_retriever_data_t;
|
||||
|
||||
bool task_queue_ctl(enum task_queue_ctl_state state, void *data);
|
||||
|
||||
void *task_queue_retriever_info_next(task_retriever_info_t **link);
|
||||
|
||||
void task_queue_retriever_info_free(task_retriever_info_t *list);
|
||||
@ -224,6 +175,18 @@ void task_queue_unset_threaded(void);
|
||||
|
||||
bool task_queue_is_threaded(void);
|
||||
|
||||
bool task_queue_find(task_finder_data_t *find_data);
|
||||
|
||||
void task_queue_retrieve(task_retriever_data_t *data);
|
||||
|
||||
void task_queue_check(void);
|
||||
|
||||
void task_queue_push(retro_task_t *task);
|
||||
|
||||
void task_queue_wait(void);
|
||||
|
||||
void task_queue_reset(void);
|
||||
|
||||
/* Deinitializes the task system.
|
||||
* This deinitializes the task system.
|
||||
* The tasks that are running at
|
||||
|
@ -577,82 +577,74 @@ bool task_queue_is_threaded(void)
|
||||
return task_threaded_enable;
|
||||
}
|
||||
|
||||
bool task_queue_ctl(enum task_queue_ctl_state state, void *data)
|
||||
bool task_queue_find(task_finder_data_t *find_data)
|
||||
{
|
||||
if (!impl_current->find(find_data->func, find_data->userdata))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void task_queue_retrieve(task_retriever_data_t *data)
|
||||
{
|
||||
impl_current->retrieve(data);
|
||||
}
|
||||
|
||||
void task_queue_check(void)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case TASK_QUEUE_CTL_FIND:
|
||||
{
|
||||
task_finder_data_t *find_data = (task_finder_data_t*)data;
|
||||
if (!impl_current->find(find_data->func, find_data->userdata))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TASK_QUEUE_CTL_RETRIEVE:
|
||||
impl_current->retrieve((task_retriever_data_t*)data);
|
||||
break;
|
||||
case TASK_QUEUE_CTL_CHECK:
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
bool current_threaded = (impl_current == &impl_threaded);
|
||||
bool want_threaded = task_queue_is_threaded();
|
||||
bool current_threaded = (impl_current == &impl_threaded);
|
||||
bool want_threaded = task_queue_is_threaded();
|
||||
|
||||
if (want_threaded != current_threaded)
|
||||
task_queue_deinit();
|
||||
if (want_threaded != current_threaded)
|
||||
task_queue_deinit();
|
||||
|
||||
if (!impl_current)
|
||||
task_queue_init(want_threaded, msg_push_bak);
|
||||
if (!impl_current)
|
||||
task_queue_init(want_threaded, msg_push_bak);
|
||||
#endif
|
||||
|
||||
impl_current->gather();
|
||||
}
|
||||
break;
|
||||
case TASK_QUEUE_CTL_PUSH:
|
||||
impl_current->gather();
|
||||
}
|
||||
|
||||
void task_queue_push(retro_task_t *task)
|
||||
{
|
||||
/* Ignore this task if a related one is already running */
|
||||
if (task->type == TASK_TYPE_BLOCKING)
|
||||
{
|
||||
retro_task_t *running = NULL;
|
||||
bool found = false;
|
||||
|
||||
SLOCK_LOCK(queue_lock);
|
||||
running = tasks_running.front;
|
||||
|
||||
for (; running; running = running->next)
|
||||
{
|
||||
if (running->type == TASK_TYPE_BLOCKING)
|
||||
{
|
||||
retro_task_t *task = (retro_task_t*)data;
|
||||
|
||||
/* Ignore this task if a related one is already running */
|
||||
if (task->type == TASK_TYPE_BLOCKING)
|
||||
{
|
||||
retro_task_t *running = NULL;
|
||||
bool found = false;
|
||||
|
||||
SLOCK_LOCK(queue_lock);
|
||||
running = tasks_running.front;
|
||||
|
||||
for (; running; running = running->next)
|
||||
{
|
||||
if (running->type == TASK_TYPE_BLOCKING)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SLOCK_UNLOCK(queue_lock);
|
||||
|
||||
/* skip this task, user must try again later */
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
/* The lack of NULL checks in the following functions
|
||||
* is proposital to ensure correct control flow by the users. */
|
||||
impl_current->push_running(task);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case TASK_QUEUE_CTL_RESET:
|
||||
impl_current->reset();
|
||||
break;
|
||||
case TASK_QUEUE_CTL_WAIT:
|
||||
impl_current->wait();
|
||||
break;
|
||||
case TASK_QUEUE_CTL_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SLOCK_UNLOCK(queue_lock);
|
||||
|
||||
/* skip this task, user must try again later */
|
||||
if (found)
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
/* The lack of NULL checks in the following functions
|
||||
* is proposital to ensure correct control flow by the users. */
|
||||
impl_current->push_running(task);
|
||||
}
|
||||
|
||||
void task_queue_wait(void)
|
||||
{
|
||||
impl_current->wait();
|
||||
}
|
||||
|
||||
void task_queue_reset(void)
|
||||
{
|
||||
impl_current->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ static int action_select_default(const char *path, const char *label, unsigned t
|
||||
if (action != MENU_ACTION_NOOP)
|
||||
ret = menu_entry_action(&entry, (unsigned)idx, action);
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
task_queue_check();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ bool input_autoconfigure_disconnect(unsigned i, const char *ident)
|
||||
task->state = state;
|
||||
task->handler = input_autoconfigure_disconnect_handler;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
@ -475,7 +475,7 @@ bool input_autoconfigure_connect(
|
||||
task->state = state;
|
||||
task->handler = input_autoconfigure_connect_handler;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -736,7 +736,7 @@ bool task_push_dbscan(
|
||||
if (db->handle)
|
||||
db->handle->status = DATABASE_STATUS_ITERATE_BEGIN;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
|
||||
task_queue_push(t);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -247,7 +247,7 @@ bool task_check_decompress(const char *source_file)
|
||||
find_data.userdata = (void *)source_file;
|
||||
|
||||
/* Return whether decompressing is in progress or not */
|
||||
return task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data);
|
||||
return task_queue_find(&find_data);
|
||||
}
|
||||
|
||||
bool task_push_decompress(
|
||||
@ -332,7 +332,7 @@ bool task_push_decompress(
|
||||
|
||||
t->title = strdup(tmp);
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
|
||||
task_queue_push(t);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -255,7 +255,7 @@ static void* task_push_http_transfer_generic(
|
||||
find_data.userdata = (void*)url;
|
||||
|
||||
/* Concurrent download of the same file is not allowed */
|
||||
if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data))
|
||||
if (task_queue_find(&find_data))
|
||||
{
|
||||
RARCH_LOG("[http] '%s'' is already being downloaded.\n", url);
|
||||
return NULL;
|
||||
@ -295,7 +295,7 @@ static void* task_push_http_transfer_generic(
|
||||
|
||||
t->title = strdup(tmp);
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
|
||||
task_queue_push(t);
|
||||
|
||||
return t;
|
||||
|
||||
@ -341,6 +341,7 @@ task_retriever_info_t *http_task_get_transfer_list(void)
|
||||
retrieve_data.func = task_http_retriever;
|
||||
|
||||
/* Build list of current HTTP transfers and return it */
|
||||
task_queue_ctl(TASK_QUEUE_CTL_RETRIEVE, &retrieve_data);
|
||||
task_queue_retrieve(&retrieve_data);
|
||||
|
||||
return retrieve_data.list;
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ bool task_push_image_load(const char *fullpath, retro_task_callback_t cb, void *
|
||||
t->callback = cb;
|
||||
t->user_data = user_data;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
|
||||
task_queue_push(t);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -307,7 +307,7 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name,
|
||||
task->callback = netplay_crc_scan_callback;
|
||||
task->title = strdup("Looking for matching content...");
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -104,7 +104,7 @@ bool task_push_netplay_lan_scan(void)
|
||||
task->callback = netplay_lan_scan_callback;
|
||||
task->title = strdup(msg_hash_to_str(MSG_NETPLAY_LAN_SCANNING));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -121,7 +121,7 @@ bool task_push_netplay_lan_scan_rooms(void)
|
||||
task->callback = netplay_lan_scan_callback;
|
||||
task->title = strdup(msg_hash_to_str(MSG_NETPLAY_LAN_SCANNING));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ bool task_push_netplay_nat_traversal(void *nat_traversal_state, uint16_t port)
|
||||
task->callback = netplay_nat_traversal_callback;
|
||||
task->task_data = ntsd;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
#else
|
||||
|
@ -760,7 +760,8 @@ bool task_push_overlay_load_default(
|
||||
/* Prevent overlay from being loaded if it already is being loaded */
|
||||
find_data.func = task_overlay_finder;
|
||||
find_data.userdata = (void*)overlay_path;
|
||||
if (task_queue_ctl(TASK_QUEUE_CTL_FIND, &find_data))
|
||||
|
||||
if (task_queue_find(&find_data))
|
||||
goto error;
|
||||
|
||||
conf = config_file_new(overlay_path);
|
||||
@ -800,7 +801,7 @@ bool task_push_overlay_load_default(
|
||||
t->callback = cb;
|
||||
t->user_data = user_data;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, t);
|
||||
task_queue_push(t);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -75,5 +75,5 @@ void task_push_get_powerstate(void)
|
||||
task->callback = task_powerstate_cb;
|
||||
task->mute = true;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ static bool task_push_undo_save_state(const char *path, void *data, size_t size)
|
||||
task->callback = undo_save_state_cb;
|
||||
task->title = strdup(msg_hash_to_str(MSG_UNDOING_SAVE_STATE));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
@ -1018,7 +1018,7 @@ static void task_push_save_state(const char *path, void *data, size_t size, bool
|
||||
task->title = strdup(msg_hash_to_str(MSG_SAVING_STATE));
|
||||
task->mute = state->mute;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return;
|
||||
|
||||
@ -1089,7 +1089,7 @@ static void task_push_load_and_save_state(const char *path, void *data,
|
||||
task->title = strdup(msg_hash_to_str(MSG_LOADING_STATE));
|
||||
task->mute = state->mute;
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return;
|
||||
|
||||
@ -1225,7 +1225,7 @@ bool content_load_state(const char *path,
|
||||
task->callback = content_load_state_cb;
|
||||
task->title = strdup(msg_hash_to_str(MSG_LOADING_STATE));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -267,7 +267,7 @@ static bool screenshot_dump(
|
||||
if (!savestate)
|
||||
task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ bool task_push_wifi_scan(void)
|
||||
task->title = strdup(msg_hash_to_str(
|
||||
MSG_SCANNING_WIRELESS_NETWORKS));
|
||||
|
||||
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -769,7 +769,7 @@ didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)menuSelect: (uint32_t) i
|
||||
{
|
||||
menu_entry_select(i);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
task_queue_check();
|
||||
}
|
||||
|
||||
- (void)menuBack
|
||||
|
@ -239,7 +239,7 @@ static char** waiting_argv;
|
||||
ret = runloop_iterate(&sleep_ms);
|
||||
if (ret == 1 && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
task_queue_check();
|
||||
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, FALSE) == kCFRunLoopRunHandledSource);
|
||||
if (ret == -1)
|
||||
break;
|
||||
|
@ -88,7 +88,7 @@ static void rarch_draw_observer(CFRunLoopObserverRef observer,
|
||||
|
||||
if (ret == 1 && !ui_companion_is_on_foreground() && sleep_ms > 0)
|
||||
retro_sleep(sleep_ms);
|
||||
task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL);
|
||||
task_queue_check();
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user