state_file: save only if something has changed
If nothing has changed since the last save, don't save the state file. Saving will spin up the hard drive, which is undesirable on hosts where MPD is idling in background.
This commit is contained in:
parent
1e663b1869
commit
ecb118f1ed
1
NEWS
1
NEWS
@ -36,6 +36,7 @@ ver 0.16 (20??/??/??)
|
||||
* renamed option "--stdout" to "--stderr"
|
||||
* removed options --create-db and --no-create-db
|
||||
* automatically update the database with Linux inotify
|
||||
* state_file: save only if something has changed
|
||||
* obey $(sysconfdir) for default mpd.conf location
|
||||
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "mixer_control.h"
|
||||
#include "idle.h"
|
||||
|
||||
extern unsigned audio_output_state_version;
|
||||
|
||||
bool
|
||||
audio_output_enable_index(unsigned idx)
|
||||
{
|
||||
@ -44,6 +46,8 @@ audio_output_enable_index(unsigned idx)
|
||||
ao->enabled = true;
|
||||
idle_add(IDLE_OUTPUT);
|
||||
|
||||
++audio_output_state_version;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -67,5 +71,7 @@ audio_output_disable_index(unsigned idx)
|
||||
idle_add(IDLE_MIXER);
|
||||
}
|
||||
|
||||
++audio_output_state_version;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
#define AUDIO_DEVICE_STATE "audio_device_state:"
|
||||
|
||||
unsigned audio_output_state_version;
|
||||
|
||||
void
|
||||
audio_output_state_save(FILE *fp)
|
||||
{
|
||||
@ -80,3 +82,9 @@ audio_output_state_read(const char *line)
|
||||
ao->enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned
|
||||
audio_output_state_get_version(void)
|
||||
{
|
||||
return audio_output_state_version;
|
||||
}
|
||||
|
@ -34,4 +34,12 @@ audio_output_state_read(const char *line);
|
||||
void
|
||||
audio_output_state_save(FILE *fp);
|
||||
|
||||
/**
|
||||
* Generates a version number for the current state of the audio
|
||||
* outputs. This is used by timer_save_state_file() to determine
|
||||
* whether the state has changed and the state file should be saved.
|
||||
*/
|
||||
unsigned
|
||||
audio_output_state_get_version(void);
|
||||
|
||||
#endif
|
||||
|
@ -200,3 +200,21 @@ playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned
|
||||
playlist_state_get_hash(const struct playlist *playlist)
|
||||
{
|
||||
return playlist->queue.version ^
|
||||
(getPlayerElapsedTime() << 8) ^
|
||||
(playlist->current >= 0
|
||||
? (queue_order_to_position(&playlist->queue,
|
||||
playlist->current) << 16)
|
||||
: 0) ^
|
||||
((int)getPlayerCrossFade() << 20) ^
|
||||
(getPlayerState() << 24) ^
|
||||
(playlist->queue.random << 27) ^
|
||||
(playlist->queue.repeat << 28) ^
|
||||
(playlist->queue.single << 29) ^
|
||||
(playlist->queue.consume << 30) ^
|
||||
(playlist->queue.random << 31);
|
||||
}
|
||||
|
@ -36,4 +36,13 @@ playlist_state_save(FILE *fp, const struct playlist *playlist);
|
||||
bool
|
||||
playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist);
|
||||
|
||||
/**
|
||||
* Generates a hash number for the current state of the playlist and
|
||||
* the playback options. This is used by timer_save_state_file() to
|
||||
* determine whether the state has changed and the state file should
|
||||
* be saved.
|
||||
*/
|
||||
unsigned
|
||||
playlist_state_get_hash(const struct playlist *playlist);
|
||||
|
||||
#endif
|
||||
|
@ -36,6 +36,13 @@ static char *state_file_path;
|
||||
/** the GLib source id for the save timer */
|
||||
static guint save_state_source_id;
|
||||
|
||||
/**
|
||||
* These version numbers determine whether we need to save the state
|
||||
* file. If nothing has changed, we won't let the hard drive spin up.
|
||||
*/
|
||||
static unsigned prev_volume_version, prev_output_version,
|
||||
prev_playlist_version;
|
||||
|
||||
static void
|
||||
state_file_write(void)
|
||||
{
|
||||
@ -57,6 +64,10 @@ state_file_write(void)
|
||||
playlist_state_save(fp, &g_playlist);
|
||||
|
||||
while(fclose(fp) && errno == EINTR) /* nothing */;
|
||||
|
||||
prev_volume_version = sw_volume_state_get_hash();
|
||||
prev_output_version = audio_output_state_get_version();
|
||||
prev_playlist_version = playlist_state_get_hash(&g_playlist);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -88,6 +99,10 @@ state_file_read(void)
|
||||
}
|
||||
|
||||
while(fclose(fp) && errno == EINTR) /* nothing */;
|
||||
|
||||
prev_volume_version = sw_volume_state_get_hash();
|
||||
prev_output_version = audio_output_state_get_version();
|
||||
prev_playlist_version = playlist_state_get_hash(&g_playlist);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,6 +112,13 @@ state_file_read(void)
|
||||
static gboolean
|
||||
timer_save_state_file(G_GNUC_UNUSED gpointer data)
|
||||
{
|
||||
if (prev_volume_version == sw_volume_state_get_hash() &&
|
||||
prev_output_version == audio_output_state_get_version() &&
|
||||
prev_playlist_version == playlist_state_get_hash(&g_playlist))
|
||||
/* nothing has changed - don't save the state file,
|
||||
don't spin up the hard disk */
|
||||
return true;
|
||||
|
||||
state_file_write();
|
||||
return true;
|
||||
}
|
||||
|
@ -122,3 +122,9 @@ void save_sw_volume_state(FILE *fp)
|
||||
{
|
||||
fprintf(fp, SW_VOLUME_STATE "%u\n", volume_software_set);
|
||||
}
|
||||
|
||||
unsigned
|
||||
sw_volume_state_get_hash(void)
|
||||
{
|
||||
return volume_software_set;
|
||||
}
|
||||
|
@ -36,4 +36,13 @@ read_sw_volume_state(const char *line);
|
||||
|
||||
void save_sw_volume_state(FILE *fp);
|
||||
|
||||
/**
|
||||
* Generates a hash number for the current state of the software
|
||||
* volume control. This is used by timer_save_state_file() to
|
||||
* determine whether the state has changed and the state file should
|
||||
* be saved.
|
||||
*/
|
||||
unsigned
|
||||
sw_volume_state_get_hash(void);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user