mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-07 05:35:02 -05:00
Hopefully get shutdown/exit handling on SDL/maemo right.
Make shutdown_hw() not return as it's supposed to, ensure sim_do_exit() is called from main thread and move sim_kernel_shutdown() into it to simplify things. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29455 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
d69d406e09
commit
d8f6c75ab9
6 changed files with 45 additions and 51 deletions
|
|
@ -23,7 +23,6 @@
|
||||||
#include <libhal.h>
|
#include <libhal.h>
|
||||||
#include <libosso.h>
|
#include <libosso.h>
|
||||||
#include <SDL_thread.h>
|
#include <SDL_thread.h>
|
||||||
#include <SDL_events.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
@ -212,15 +211,6 @@ void reset_poweroff_timer(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown_hw(void)
|
|
||||||
{
|
|
||||||
/* Shut down SDL event loop */
|
|
||||||
SDL_Event event;
|
|
||||||
memset(&event, 0, sizeof(SDL_Event));
|
|
||||||
event.type = SDL_USEREVENT;
|
|
||||||
SDL_PushEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cancel_shutdown(void)
|
void cancel_shutdown(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -275,8 +275,8 @@ static bool event_handler(SDL_Event *event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
/* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */
|
/* Will post SDL_USEREVENT in shutdown_hw() if successful. */
|
||||||
queue_broadcast(SYS_POWEROFF, 0);
|
sys_poweroff();
|
||||||
break;
|
break;
|
||||||
case SDL_USEREVENT:
|
case SDL_USEREVENT:
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -324,8 +324,8 @@ static void button_event(int key, bool pressed)
|
||||||
|
|
||||||
#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
|
#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
|
||||||
case SDLK_LCTRL:
|
case SDLK_LCTRL:
|
||||||
/* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */
|
/* Will post SDL_USEREVENT in shutdown_hw() if successful. */
|
||||||
queue_broadcast(SYS_POWEROFF, 0);
|
sys_poweroff();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_BUTTON_HOLD
|
#ifdef HAS_BUTTON_HOLD
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,8 @@ long start_tick;
|
||||||
|
|
||||||
#ifndef HAVE_SDL_THREADS
|
#ifndef HAVE_SDL_THREADS
|
||||||
/* for the wait_for_interrupt function */
|
/* for the wait_for_interrupt function */
|
||||||
static bool do_exit;
|
|
||||||
static SDL_cond *wfi_cond;
|
static SDL_cond *wfi_cond;
|
||||||
static SDL_mutex *wfi_mutex;
|
static SDL_mutex *wfi_mutex;
|
||||||
#else
|
|
||||||
#define do_exit false
|
|
||||||
#endif
|
#endif
|
||||||
/* Condition to signal that "interrupts" may proceed */
|
/* Condition to signal that "interrupts" may proceed */
|
||||||
static SDL_cond *sim_thread_cond;
|
static SDL_cond *sim_thread_cond;
|
||||||
|
|
@ -74,7 +71,7 @@ int set_irq_level(int level)
|
||||||
/* Not in a handler and "interrupts" are going from disabled to
|
/* Not in a handler and "interrupts" are going from disabled to
|
||||||
* enabled; signal any pending handlers still waiting */
|
* enabled; signal any pending handlers still waiting */
|
||||||
if (handlers_pending > 0)
|
if (handlers_pending > 0)
|
||||||
SDL_CondSignal(sim_thread_cond);
|
SDL_CondBroadcast(sim_thread_cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt_level = level; /* save new level */
|
interrupt_level = level; /* save new level */
|
||||||
|
|
@ -147,10 +144,14 @@ void sim_kernel_shutdown(void)
|
||||||
{
|
{
|
||||||
SDL_RemoveTimer(tick_timer_id);
|
SDL_RemoveTimer(tick_timer_id);
|
||||||
#ifndef HAVE_SDL_THREADS
|
#ifndef HAVE_SDL_THREADS
|
||||||
do_exit = true;
|
SDL_DestroyCond(wfi_cond);
|
||||||
SDL_CondSignal(wfi_cond);
|
SDL_UnlockMutex(wfi_mutex);
|
||||||
|
SDL_DestroyMutex(wfi_mutex);
|
||||||
#endif
|
#endif
|
||||||
disable_irq();
|
enable_irq();
|
||||||
|
while(handlers_pending > 0)
|
||||||
|
SDL_Delay(10);
|
||||||
|
|
||||||
SDL_DestroyMutex(sim_irq_mtx);
|
SDL_DestroyMutex(sim_irq_mtx);
|
||||||
SDL_DestroyCond(sim_thread_cond);
|
SDL_DestroyCond(sim_thread_cond);
|
||||||
}
|
}
|
||||||
|
|
@ -164,7 +165,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
|
||||||
|
|
||||||
new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
|
new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
|
||||||
|
|
||||||
while(new_tick != current_tick && !do_exit)
|
while(new_tick != current_tick)
|
||||||
{
|
{
|
||||||
sim_enter_irq_handler();
|
sim_enter_irq_handler();
|
||||||
|
|
||||||
|
|
@ -175,7 +176,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
|
||||||
sim_exit_irq_handler();
|
sim_exit_irq_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
return do_exit ? 0 : interval;
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
|
|
@ -203,23 +204,10 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_SDL_THREADS
|
#ifndef HAVE_SDL_THREADS
|
||||||
static void check_exit(void)
|
|
||||||
{
|
|
||||||
if (UNLIKELY(do_exit))
|
|
||||||
{
|
|
||||||
SDL_DestroyCond(wfi_cond);
|
|
||||||
SDL_UnlockMutex(wfi_mutex);
|
|
||||||
SDL_DestroyMutex(wfi_mutex);
|
|
||||||
sim_do_exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_for_interrupt(void)
|
void wait_for_interrupt(void)
|
||||||
{
|
{
|
||||||
/* the exit may come at any time, during the CondWait or before,
|
/* the exit may come at any time, during the CondWait or before,
|
||||||
* so check it twice */
|
* so check it twice */
|
||||||
check_exit();
|
|
||||||
SDL_CondWait(wfi_cond, wfi_mutex);
|
SDL_CondWait(wfi_cond, wfi_mutex);
|
||||||
check_exit();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,10 @@ bool debug_audio = false;
|
||||||
bool debug_wps = false;
|
bool debug_wps = false;
|
||||||
int wps_verbose_level = 3;
|
int wps_verbose_level = 3;
|
||||||
|
|
||||||
|
|
||||||
void sys_poweroff(void)
|
void sys_poweroff(void)
|
||||||
{
|
{
|
||||||
|
/* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */
|
||||||
|
queue_broadcast(SYS_POWEROFF, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -187,16 +188,39 @@ static int sdl_event_thread(void * param)
|
||||||
#ifdef HAVE_SDL_THREADS
|
#ifdef HAVE_SDL_THREADS
|
||||||
sim_thread_shutdown(); /* not needed for native threads */
|
sim_thread_shutdown(); /* not needed for native threads */
|
||||||
#endif
|
#endif
|
||||||
sim_kernel_shutdown();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_do_exit(void)
|
void shutdown_hw(void)
|
||||||
{
|
{
|
||||||
|
/* Shut down SDL event loop */
|
||||||
|
SDL_Event event;
|
||||||
|
memset(&event, 0, sizeof(SDL_Event));
|
||||||
|
event.type = SDL_USEREVENT;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
#ifdef HAVE_SDL_THREADS
|
||||||
|
/* since sim_thread_shutdown() grabs the mutex we need to let it free,
|
||||||
|
* otherwise SDL_WaitThread will deadlock */
|
||||||
|
struct thread_entry* t = sim_thread_unlock();
|
||||||
|
#endif
|
||||||
/* wait for event thread to finish */
|
/* wait for event thread to finish */
|
||||||
SDL_WaitThread(evt_thread, NULL);
|
SDL_WaitThread(evt_thread, NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_SDL_THREADS
|
||||||
|
/* lock again before entering the scheduler */
|
||||||
|
sim_thread_lock(t);
|
||||||
|
/* sim_thread_shutdown() will cause sim_do_exit() to be called via longjmp,
|
||||||
|
* but only if we let the sdl thread scheduler exit the other threads */
|
||||||
|
while(1) yield();
|
||||||
|
#else
|
||||||
|
sim_do_exit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void sim_do_exit()
|
||||||
|
{
|
||||||
|
sim_kernel_shutdown();
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
#define _SYSTEM_SDL_H_
|
#define _SYSTEM_SDL_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "gcc_extensions.h"
|
||||||
|
|
||||||
#define HIGHEST_IRQ_LEVEL 1
|
#define HIGHEST_IRQ_LEVEL 1
|
||||||
|
|
||||||
|
|
@ -45,7 +47,7 @@ void sim_kernel_shutdown(void);
|
||||||
void sys_poweroff(void);
|
void sys_poweroff(void);
|
||||||
void sys_handle_argv(int argc, char *argv[]);
|
void sys_handle_argv(int argc, char *argv[]);
|
||||||
void gui_message_loop(void);
|
void gui_message_loop(void);
|
||||||
void sim_do_exit(void);
|
void sim_do_exit(void) NORETURN_ATTR;
|
||||||
#ifndef HAVE_SDL_THREADS
|
#ifndef HAVE_SDL_THREADS
|
||||||
void wait_for_interrupt(void);
|
void wait_for_interrupt(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "powermgmt.h"
|
#include "powermgmt.h"
|
||||||
#include <SDL_events.h>
|
|
||||||
|
|
||||||
#define BATT_MINMVOLT 2500 /* minimum millivolts of battery */
|
#define BATT_MINMVOLT 2500 /* minimum millivolts of battery */
|
||||||
#define BATT_MAXMVOLT 4500 /* maximum millivolts of battery */
|
#define BATT_MAXMVOLT 4500 /* maximum millivolts of battery */
|
||||||
|
|
@ -154,15 +153,6 @@ void reset_poweroff_timer(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown_hw(void)
|
|
||||||
{
|
|
||||||
/* Shut down SDL event loop */
|
|
||||||
SDL_Event event;
|
|
||||||
memset(&event, 0, sizeof(SDL_Event));
|
|
||||||
event.type = SDL_USEREVENT;
|
|
||||||
SDL_PushEvent(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cancel_shutdown(void)
|
void cancel_shutdown(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue