Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
b9659ba0
Commit
b9659ba0
authored
Dec 18, 2017
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'v0.20.13'
release v0.20.13
parents
b6af7abb
49b9a90c
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
231 additions
and
7 deletions
+231
-7
Makefile.am
Makefile.am
+1
-0
NEWS
NEWS
+5
-1
StateFile.cxx
src/StateFile.cxx
+18
-1
StateFile.hxx
src/StateFile.hxx
+4
-0
Directory.cxx
src/db/plugins/simple/Directory.cxx
+1
-1
Mount.cxx
src/db/plugins/simple/Mount.cxx
+2
-2
Mount.hxx
src/db/plugins/simple/Mount.hxx
+1
-1
SimpleDatabasePlugin.cxx
src/db/plugins/simple/SimpleDatabasePlugin.cxx
+13
-0
AlsaMixerPlugin.cxx
src/mixer/plugins/AlsaMixerPlugin.cxx
+3
-1
StorageState.cxx
src/storage/StorageState.cxx
+137
-0
StorageState.hxx
src/storage/StorageState.hxx
+46
-0
No files found.
Makefile.am
View file @
b9659ba0
...
...
@@ -721,6 +721,7 @@ libstorage_a_SOURCES = \
src/storage/MemoryDirectoryReader.cxx src/storage/MemoryDirectoryReader.hxx
\
src/storage/Configured.cxx src/storage/Configured.hxx
\
src/storage/plugins/LocalStorage.cxx src/storage/plugins/LocalStorage.hxx
\
src/storage/StorageState.cxx src/storage/StorageState.hxx
\
src/storage/FileInfo.hxx
libstorage_a_CPPFLAGS
=
$(AM_CPPFLAGS)
\
...
...
NEWS
View file @
b9659ba0
...
...
@@ -15,14 +15,18 @@ ver 0.21 (not yet released)
* mixer
- sndio: new mixer plugin
ver 0.20.13 (
not yet released
)
ver 0.20.13 (
2017/12/18
)
* output
- osx: set up ring buffer to hold at least 100ms
* mixer
- alsa: fix rounding errors
* database
- simple: don't purge mount points on update/rescan
- simple: fix "mount" bug caused by bad compiler optimization
- simple: fix "lsinfo" into mount points
- upnp: work around libupnp 1.6.24 API breakage
* queue: fix spuriously misplaced prioritized songs
* save and restore mountpoints within the state file
* include Windows cross-build script in source tarball
* fix Windows build failures
...
...
src/StateFile.cxx
View file @
b9659ba0
...
...
@@ -24,6 +24,7 @@
#include "fs/io/TextFile.hxx"
#include "fs/io/FileOutputStream.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "storage/StorageState.hxx"
#include "Partition.hxx"
#include "Instance.hxx"
#include "mixer/Volume.hxx"
...
...
@@ -56,6 +57,9 @@ StateFile::RememberVersions() noexcept
prev_output_version
=
audio_output_state_get_version
();
prev_playlist_version
=
playlist_state_get_hash
(
partition
.
playlist
,
partition
.
pc
);
#ifdef ENABLE_DATABASE
prev_storage_version
=
storage_state_get_hash
(
partition
.
instance
);
#endif
}
bool
...
...
@@ -64,7 +68,11 @@ StateFile::IsModified() const noexcept
return
prev_volume_version
!=
sw_volume_state_get_hash
()
||
prev_output_version
!=
audio_output_state_get_version
()
||
prev_playlist_version
!=
playlist_state_get_hash
(
partition
.
playlist
,
partition
.
pc
);
partition
.
pc
)
#ifdef ENABLE_DATABASE
||
prev_storage_version
!=
storage_state_get_hash
(
partition
.
instance
)
#endif
;
}
inline
void
...
...
@@ -72,6 +80,11 @@ StateFile::Write(BufferedOutputStream &os)
{
save_sw_volume_state
(
os
);
audio_output_state_save
(
os
,
partition
.
outputs
);
#ifdef ENABLE_DATABASE
storage_state_save
(
os
,
partition
.
instance
);
#endif
playlist_state_save
(
os
,
partition
.
playlist
,
partition
.
pc
);
}
...
...
@@ -123,6 +136,10 @@ try {
playlist_state_restore
(
line
,
file
,
song_loader
,
partition
.
playlist
,
partition
.
pc
);
#ifdef ENABLE_DATABASE
success
=
success
||
storage_state_restore
(
line
,
file
,
partition
.
instance
);
#endif
if
(
!
success
)
FormatError
(
state_file_domain
,
"Unrecognized line in state file: %s"
,
...
...
src/StateFile.hxx
View file @
b9659ba0
...
...
@@ -47,6 +47,10 @@ class StateFile final {
unsigned
prev_volume_version
=
0
,
prev_output_version
=
0
,
prev_playlist_version
=
0
;
#ifdef ENABLE_DATABASE
unsigned
prev_storage_version
=
0
;
#endif
public
:
static
constexpr
std
::
chrono
::
steady_clock
::
duration
DEFAULT_INTERVAL
=
std
::
chrono
::
minutes
(
2
);
...
...
src/db/plugins/simple/Directory.cxx
View file @
b9659ba0
...
...
@@ -227,7 +227,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
call will lock it again */
const
ScopeDatabaseUnlock
unlock
;
WalkMount
(
GetPath
(),
*
mounted_database
,
recursive
,
filter
,
""
,
recursive
,
filter
,
visit_directory
,
visit_song
,
visit_playlist
);
return
;
...
...
src/db/plugins/simple/Mount.cxx
View file @
b9659ba0
...
...
@@ -72,7 +72,7 @@ PrefixVisitPlaylist(const char *base, const VisitPlaylist &visit_playlist,
void
WalkMount
(
const
char
*
base
,
const
Database
&
db
,
bool
recursive
,
const
SongFilter
*
filter
,
const
char
*
uri
,
bool
recursive
,
const
SongFilter
*
filter
,
const
VisitDirectory
&
visit_directory
,
const
VisitSong
&
visit_song
,
const
VisitPlaylist
&
visit_playlist
)
{
...
...
@@ -93,5 +93,5 @@ WalkMount(const char *base, const Database &db,
vp
=
std
::
bind
(
PrefixVisitPlaylist
,
base
,
std
::
ref
(
visit_playlist
),
_1
,
_2
);
db
.
Visit
(
DatabaseSelection
(
""
,
recursive
,
filter
),
vd
,
vs
,
vp
);
db
.
Visit
(
DatabaseSelection
(
uri
,
recursive
,
filter
),
vd
,
vs
,
vp
);
}
src/db/plugins/simple/Mount.hxx
View file @
b9659ba0
...
...
@@ -27,7 +27,7 @@ class SongFilter;
void
WalkMount
(
const
char
*
base
,
const
Database
&
db
,
bool
recursive
,
const
SongFilter
*
filter
,
const
char
*
uri
,
bool
recursive
,
const
SongFilter
*
filter
,
const
VisitDirectory
&
visit_directory
,
const
VisitSong
&
visit_song
,
const
VisitPlaylist
&
visit_playlist
);
...
...
src/db/plugins/simple/SimpleDatabasePlugin.cxx
View file @
b9659ba0
...
...
@@ -20,6 +20,7 @@
#include "config.h"
#include "SimpleDatabasePlugin.hxx"
#include "PrefixedLightSong.hxx"
#include "Mount.hxx"
#include "db/DatabasePlugin.hxx"
#include "db/Selection.hxx"
#include "db/Helpers.hxx"
...
...
@@ -271,6 +272,18 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
ScopeDatabaseLock
protect
;
auto
r
=
root
->
LookupDirectory
(
selection
.
uri
.
c_str
());
if
(
r
.
directory
->
IsMount
())
{
/* pass the request and the remaining uri to the mounted database */
protect
.
unlock
();
WalkMount
(
r
.
directory
->
GetPath
(),
*
(
r
.
directory
->
mounted_database
),
(
r
.
uri
==
nullptr
)
?
""
:
r
.
uri
,
selection
.
recursive
,
selection
.
filter
,
visit_directory
,
visit_song
,
visit_playlist
);
return
;
}
if
(
r
.
uri
==
nullptr
)
{
/* it's a directory */
...
...
src/mixer/plugins/AlsaMixerPlugin.cxx
View file @
b9659ba0
...
...
@@ -282,7 +282,9 @@ AlsaMixer::SetVolume(unsigned volume)
{
assert
(
handle
!=
nullptr
);
int
err
=
set_normalized_playback_volume
(
elem
,
0.01
*
volume
,
1
);
double
cur
=
get_normalized_playback_volume
(
elem
,
SND_MIXER_SCHN_FRONT_LEFT
);
int
delta
=
volume
-
lrint
(
100.
*
cur
);
int
err
=
set_normalized_playback_volume
(
elem
,
cur
+
0.01
*
delta
,
delta
);
if
(
err
<
0
)
throw
FormatRuntimeError
(
"failed to set ALSA volume: %s"
,
snd_strerror
(
err
));
...
...
src/storage/StorageState.cxx
0 → 100644
View file @
b9659ba0
/*
* Copyright 2003-2017 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Save and load mounts of the compound storage to/from the state file.
*
*/
#include "config.h"
#include "StorageState.hxx"
#include "fs/io/TextFile.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "storage/Registry.hxx"
#include "storage/CompositeStorage.hxx"
#include "db/plugins/simple/SimpleDatabasePlugin.hxx"
#include "util/StringCompare.hxx"
#include "util/Domain.hxx"
#include "Instance.hxx"
#include "Log.hxx"
#include <list>
#include <boost/crc.hpp>
#define MOUNT_STATE_BEGIN "mount_begin"
#define MOUNT_STATE_END "mount_end"
#define MOUNT_STATE_STORAGE_URI "uri: "
#define MOUNT_STATE_MOUNTED_URL "mounted_url: "
static
constexpr
Domain
storage_domain
(
"storage"
);
void
storage_state_save
(
BufferedOutputStream
&
os
,
const
Instance
&
instance
)
{
const
auto
visitor
=
[
&
os
](
const
char
*
mount_uri
,
const
Storage
&
storage
)
{
std
::
string
uri
=
storage
.
MapUTF8
(
""
);
if
(
uri
.
empty
()
||
StringIsEmpty
(
mount_uri
))
return
;
os
.
Format
(
MOUNT_STATE_BEGIN
"
\n
"
MOUNT_STATE_STORAGE_URI
"%s
\n
"
MOUNT_STATE_MOUNTED_URL
"%s
\n
"
MOUNT_STATE_END
"
\n
"
,
mount_uri
,
uri
.
c_str
());
};
((
CompositeStorage
*
)
instance
.
storage
)
->
VisitMounts
(
visitor
);
}
bool
storage_state_restore
(
const
char
*
line
,
TextFile
&
file
,
Instance
&
instance
)
{
if
(
!
StringStartsWith
(
line
,
MOUNT_STATE_BEGIN
))
return
false
;
std
::
string
url
;
std
::
string
uri
;
const
char
*
value
;
while
((
line
=
file
.
ReadLine
())
!=
nullptr
)
{
if
(
StringStartsWith
(
line
,
MOUNT_STATE_END
))
break
;
if
((
value
=
StringAfterPrefix
(
line
,
MOUNT_STATE_MOUNTED_URL
)))
url
=
value
;
else
if
((
value
=
StringAfterPrefix
(
line
,
MOUNT_STATE_STORAGE_URI
)))
uri
=
value
;
else
FormatError
(
storage_domain
,
"Unrecognized line in mountpoint state: %s"
,
line
);
}
if
(
url
.
empty
()
||
uri
.
empty
())
{
LogError
(
storage_domain
,
"Missing value in mountpoint state."
);
return
true
;
}
FormatDebug
(
storage_domain
,
"Restoring mount %s => %s"
,
uri
.
c_str
(),
url
.
c_str
());
auto
&
event_loop
=
instance
.
io_thread
.
GetEventLoop
();
Storage
*
storage
=
CreateStorageURI
(
event_loop
,
url
.
c_str
());
if
(
storage
==
nullptr
)
{
FormatError
(
storage_domain
,
"Unrecognized storage URI: %s"
,
url
.
c_str
());
return
true
;
}
#ifdef ENABLE_DATABASE
Database
*
db
=
instance
.
database
;
if
(
db
!=
nullptr
&&
db
->
IsPlugin
(
simple_db_plugin
))
{
try
{
((
SimpleDatabase
*
)
db
)
->
Mount
(
uri
.
c_str
(),
url
.
c_str
());
}
catch
(...)
{
throw
;
}
}
#endif
((
CompositeStorage
*
)
instance
.
storage
)
->
Mount
(
uri
.
c_str
(),
storage
);
return
true
;
}
unsigned
storage_state_get_hash
(
const
Instance
&
instance
)
{
std
::
list
<
std
::
string
>
mounts
;
const
auto
visitor
=
[
&
mounts
](
const
char
*
mount_uri
,
const
Storage
&
storage
)
{
mounts
.
push_back
(
std
::
string
(
mount_uri
)
+
":"
+
storage
.
MapUTF8
(
""
));
};
((
CompositeStorage
*
)
instance
.
storage
)
->
VisitMounts
(
visitor
);
mounts
.
sort
();
boost
::
crc_32_type
result
;
for
(
auto
mount
:
mounts
)
{
result
.
process_bytes
(
mount
.
c_str
(),
mount
.
length
());
}
return
result
.
checksum
();
}
src/storage/StorageState.hxx
0 → 100644
View file @
b9659ba0
/*
* Copyright 2003-2017 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Saving and loading the playlist to/from the state file.
*
*/
#ifndef MPD_STORAGE_STATE_HXX
#define MPD_STORAGE_STATE_HXX
struct
Instance
;
class
BufferedOutputStream
;
class
TextFile
;
void
storage_state_save
(
BufferedOutputStream
&
os
,
const
Instance
&
instance
);
bool
storage_state_restore
(
const
char
*
line
,
TextFile
&
file
,
Instance
&
instance
);
/**
* Generates a hash number for the current state of the composite storage.
* This is used by timer_save_state_file() to determine whether the state
* has changed and the state file should be saved.
*/
unsigned
storage_state_get_hash
(
const
Instance
&
instance
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment