Rewrite task_queue

This commit is contained in:
twinaphex 2017-05-14 20:43:39 +02:00
parent 1345e97f8c
commit 80d9d1f143
25 changed files with 110 additions and 147 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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();
}
/**

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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)
{