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
7 years ago
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'v0.20.13'
release v0.20.13
parents
b6af7abb
49b9a90c
sisyphus
0.23.15-alt1
0.23.14-alt1
0.23.13-alt1
0.23.12-alt1
0.23.11-alt1
0.23.8-alt3
0.23.8-alt2
0.23.8-alt1
0.21.24-alt1.1
0.21.24-alt1
gb-sisyphus-task339776.6100
gb-sisyphus-task337393.100
gb-sisyphus-task337176.300
gb-sisyphus-task334590.100
gb-sisyphus-task333607.100
gb-sisyphus-task331543.2500
gb-sisyphus-task328663.4700
gb-sisyphus-task325064.100
gb-sisyphus-task319111.4000
gb-sisyphus-task313704.100
gb-sisyphus-task312885.100
gb-sisyphus-task308905.3200
gb-sisyphus-task305294.500
gb-sisyphus-task304007.100
gb-sisyphus-task303674.1700
gb-sisyphus-task298681.300
gb-sisyphus-task296051.1000
gb-sisyphus-task274827.100
gb-sisyphus-task269249.2000
gb-sisyphus-task266579.400
gb-sisyphus-task258132.600
gb-sisyphus-task254601.200
No related merge requests found
Show 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)
\
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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"
,
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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 */
...
...
This diff is collapsed.
Click to expand it.
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
));
...
...
This diff is collapsed.
Click to expand it.
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
();
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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