mplayer: never exit mplayer from within the play loop

The only place exit_player() should be called is the main() function.
exit_player() should be the only function allowed to call exit(). This
makes it easier to guarantee proper deinitialization, and allows using
the --leak-report flag without showing false positives.

The quit slave command now sets a flag only. It uses the same mechanism
that's normally used to advance to the next file on the playlist, so the
rest of the playback path should be able to react to the quit command
quickly enough. That is, the player should react just as fast to quit
requests in practice as before this commit.

In reinit_audio_chain(), the player was actually exited if
init_audio_filters() failed. Reuse the normal error handling path to
handle this condition.
This commit is contained in:
wm4 2012-08-04 03:46:11 +02:00
parent c7be71ae71
commit 9a2f4e10e7
5 changed files with 34 additions and 25 deletions

View File

@ -2872,8 +2872,9 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
break;
case MP_CMD_QUIT:
exit_player_with_rc(mpctx, EXIT_QUIT,
(cmd->nargs > 0) ? cmd->args[0].v.i : 0);
mpctx->stop_play = PT_QUIT;
mpctx->quit_player_rc = (cmd->nargs > 0) ? cmd->args[0].v.i : 0;
break;
case MP_CMD_PLAYLIST_NEXT:
case MP_CMD_PLAYLIST_PREV:

View File

@ -193,7 +193,6 @@ static int x11_errorhandler(Display * display, XErrorEvent * event)
event->error_code, event->request_code, event->minor_code);
// abort();
//exit_player("X11 error");
return 0;
#undef MSGLEN
}

View File

@ -54,6 +54,7 @@ enum stop_play_reason {
PT_NEXT_ENTRY, // prepare to play next entry in playlist
PT_CURRENT_ENTRY, // prepare to play mpctx->playlist->current
PT_STOP, // stop playback, clear playlist
PT_QUIT, // stop playback, quit player
};
enum exit_reason {
@ -99,6 +100,9 @@ typedef struct MPContext {
enum stop_play_reason stop_play;
unsigned int initialized_flags; // which subsystems have been initialized
// Return code to use with PT_QUIT
int quit_player_rc;
struct content_source *sources;
int num_sources;
struct timeline_part *timeline;
@ -227,7 +231,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask);
void reinit_audio_chain(struct MPContext *mpctx);
void init_vo_spudec(struct MPContext *mpctx);
double playing_audio_pts(struct MPContext *mpctx);
void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc);
void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr);
int reinit_video_chain(struct MPContext *mpctx);
void pause_player(struct MPContext *mpctx);

View File

@ -652,7 +652,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
}
}
void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc)
static void exit_player(struct MPContext *mpctx, enum exit_reason how, int rc)
{
uninit_player(mpctx, INITIALIZED_ALL);
#if defined(__MINGW32__) || defined(__CYGWIN__)
@ -700,11 +700,6 @@ void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc)
exit(rc);
}
static void exit_player(struct MPContext *mpctx, enum exit_reason how)
{
exit_player_with_rc(mpctx, how, 1);
}
#include "cfg-mplayer.h"
static int cfg_include(struct m_config *conf, char *filename)
@ -714,14 +709,14 @@ static int cfg_include(struct m_config *conf, char *filename)
#define DEF_CONFIG "# Write your default config options here!\n\n\n"
static void parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
{
struct MPOpts *opts = &mpctx->opts;
char *conffile;
int conffile_fd;
if (!(opts->noconfig & 2) &&
m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mplayer.conf") < 0)
exit_player(mpctx, EXIT_NONE);
return false;
if ((conffile = get_path("")) == NULL)
mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Cannot find HOME directory.\n");
else {
@ -739,10 +734,11 @@ static void parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf)
}
if (!(opts->noconfig & 1) &&
m_config_parse_config_file(conf, conffile) < 0)
exit_player(mpctx, EXIT_NONE);
return false;
free(conffile);
}
}
return true;
}
#define PROFILE_CFG_PROTOCOL "protocol."
@ -1509,7 +1505,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
&ao->samplerate, &ao->channels, &ao->format)) {
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Error at audio filter chain "
"pre-init!\n");
exit_player(mpctx, EXIT_ERROR);
goto init_error;
}
if (!ao->initialized) {
ao->buffersize = opts->ao_buffersize;
@ -3564,7 +3560,9 @@ static bool process_playlist_demuxer(struct MPContext *mpctx)
static void idle_loop(struct MPContext *mpctx)
{
// ================= idle loop (STOP state) =========================
while (mpctx->opts.player_idle_mode && !mpctx->playlist->current) {
while (mpctx->opts.player_idle_mode && !mpctx->playlist->current
&& mpctx->stop_play != PT_QUIT)
{
uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_VO);
mp_cmd_t *cmd;
while (!(cmd = mp_input_get_cmd(mpctx->input, WAKEUP_PERIOD * 1000,
@ -3818,7 +3816,7 @@ goto_enable_cache:
}
}
#endif
goto terminate_playback; // exit_player(_("Fatal error"));
goto terminate_playback;
}
/* display clip info */
@ -4033,7 +4031,12 @@ static void play_files(struct MPContext *mpctx)
{
for (;;) {
idle_loop(mpctx);
if (mpctx->stop_play == PT_QUIT)
break;
play_current_file(mpctx);
if (mpctx->stop_play == PT_QUIT)
break;
if (!mpctx->stop_play || mpctx->stop_play == AT_END_OF_FILE)
mpctx->stop_play = PT_NEXT_ENTRY;
@ -4127,7 +4130,7 @@ static bool handle_help_options(struct MPContext *mpctx)
return opt_exit;
}
static void load_codecs_conf(struct MPContext *mpctx)
static bool load_codecs_conf(struct MPContext *mpctx)
{
/* Check codecs.conf. */
if (!codecs_file || !parse_codec_cfg(codecs_file)) {
@ -4135,13 +4138,14 @@ static void load_codecs_conf(struct MPContext *mpctx)
if (!parse_codec_cfg(mem_ptr = get_path("codecs.conf"))) {
if (!parse_codec_cfg(MPLAYER_CONFDIR "/codecs.conf")) {
if (!parse_codec_cfg(NULL))
exit_player_with_rc(mpctx, EXIT_NONE, 0);
return false;
mp_tmsg(MSGT_CPLAYER, MSGL_V,
"Using built-in default codecs.conf.\n");
}
}
free(mem_ptr); // release the buffer created by get_path()
}
return true;
}
#ifdef PTW32_STATIC_LIB
@ -4238,7 +4242,8 @@ int main(int argc, char *argv[])
print_version(false);
print_libav_versions();
parse_cfgfiles(mpctx, mpctx->mconfig);
if (!parse_cfgfiles(mpctx, mpctx->mconfig))
exit_player(mpctx, EXIT_NONE, 1);
mpctx->playlist = talloc_struct(mpctx, struct playlist, {0});
if (m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist,
@ -4246,13 +4251,14 @@ int main(int argc, char *argv[])
{
mpctx->playlist->current = mpctx->playlist->first;
} else {
exit_player(mpctx, EXIT_ERROR);
exit_player(mpctx, EXIT_ERROR, 1);
}
load_codecs_conf(mpctx);
if (!load_codecs_conf(mpctx))
exit_player(mpctx, EXIT_ERROR, 1);
if (handle_help_options(mpctx))
exit_player(mpctx, EXIT_NONE);
exit_player(mpctx, EXIT_NONE, 1);
mp_msg(MSGT_CPLAYER, MSGL_V, "Configuration: " CONFIGURATION "\n");
mp_tmsg(MSGT_CPLAYER, MSGL_V, "Command line:");
@ -4264,7 +4270,7 @@ int main(int argc, char *argv[])
// no file/vcd/dvd -> show HELP:
print_version(true);
mp_msg(MSGT_CPLAYER, MSGL_INFO, "%s", mp_gtext(help_text));
exit_player_with_rc(mpctx, EXIT_NONE, 0);
exit_player(mpctx, EXIT_NONE, 0);
}
#ifdef CONFIG_PRIORITY
@ -4281,7 +4287,7 @@ int main(int argc, char *argv[])
play_files(mpctx);
exit_player_with_rc(mpctx, EXIT_EOF, 0);
exit_player(mpctx, EXIT_EOF, mpctx->quit_player_rc);
return 1;
}

View File

@ -41,7 +41,7 @@ static int recursion_depth = 0;
/// Setup the \ref Config from a config file.
/** \param config The config object.
* \param conffile Path to the config file.
* \return 1 on sucess, -1 on error.
* \return 1 on sucess, -1 on error, 0 if file not accessible.
*/
int m_config_parse_config_file(m_config_t *config, const char *conffile)
{