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
1b5c1f75
Commit
1b5c1f75
authored
Apr 26, 2019
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
input/InputStreams: pass std::unique_lock<> to various methods
parent
040573c6
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
212 additions
and
156 deletions
+212
-156
Bzip2ArchivePlugin.cxx
src/archive/plugins/Bzip2ArchivePlugin.cxx
+3
-2
Iso9660ArchivePlugin.cxx
src/archive/plugins/Iso9660ArchivePlugin.cxx
+4
-2
ZzipArchivePlugin.cxx
src/archive/plugins/ZzipArchivePlugin.cxx
+5
-4
FileCommands.cxx
src/command/FileCommands.cxx
+3
-3
FingerprintCommands.cxx
src/command/FingerprintCommands.cxx
+1
-1
Bridge.cxx
src/decoder/Bridge.cxx
+1
-1
Thread.cxx
src/decoder/Thread.cxx
+17
-11
AsyncInputStream.cxx
src/input/AsyncInputStream.cxx
+6
-4
AsyncInputStream.hxx
src/input/AsyncInputStream.hxx
+4
-2
BufferedInputStream.cxx
src/input/BufferedInputStream.cxx
+10
-7
BufferedInputStream.hxx
src/input/BufferedInputStream.hxx
+3
-2
FailingInputStream.hxx
src/input/FailingInputStream.hxx
+2
-2
IcyInputStream.cxx
src/input/IcyInputStream.cxx
+4
-3
IcyInputStream.hxx
src/input/IcyInputStream.hxx
+2
-1
InputStream.cxx
src/input/InputStream.cxx
+11
-11
InputStream.hxx
src/input/InputStream.hxx
+13
-7
ProxyInputStream.cxx
src/input/ProxyInputStream.cxx
+8
-6
ProxyInputStream.hxx
src/input/ProxyInputStream.hxx
+4
-2
RewindInputStream.cxx
src/input/RewindInputStream.cxx
+8
-6
ThreadInputStream.cxx
src/input/ThreadInputStream.cxx
+3
-2
ThreadInputStream.hxx
src/input/ThreadInputStream.hxx
+2
-1
CdioParanoiaInputPlugin.cxx
src/input/plugins/CdioParanoiaInputPlugin.cxx
+7
-4
FfmpegInputPlugin.cxx
src/input/plugins/FfmpegInputPlugin.cxx
+7
-4
FileInputPlugin.cxx
src/input/plugins/FileInputPlugin.cxx
+8
-4
SmbclientInputPlugin.cxx
src/input/plugins/SmbclientInputPlugin.cxx
+7
-4
Aiff.cxx
src/tag/Aiff.cxx
+5
-5
Aiff.hxx
src/tag/Aiff.hxx
+4
-1
ApeLoader.cxx
src/tag/ApeLoader.cxx
+5
-5
Id3Load.cxx
src/tag/Id3Load.cxx
+31
-29
Riff.cxx
src/tag/Riff.cxx
+5
-5
Riff.hxx
src/tag/Riff.hxx
+4
-1
TestRewindInputStream.cxx
test/TestRewindInputStream.cxx
+13
-12
run_input.cxx
test/run_input.cxx
+2
-2
No files found.
src/archive/plugins/Bzip2ArchivePlugin.cxx
View file @
1b5c1f75
...
...
@@ -72,7 +72,8 @@ public:
/* virtual methods from InputStream */
bool
IsEOF
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
private
:
void
Open
();
...
...
@@ -147,7 +148,7 @@ Bzip2InputStream::FillBuffer()
}
size_t
Bzip2InputStream
::
Read
(
void
*
ptr
,
size_t
length
)
Bzip2InputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
length
)
{
const
ScopeUnlock
unlock
(
mutex
);
...
...
src/archive/plugins/Iso9660ArchivePlugin.cxx
View file @
1b5c1f75
...
...
@@ -157,7 +157,8 @@ public:
/* virtual methods from InputStream */
bool
IsEOF
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
};
InputStreamPtr
...
...
@@ -174,7 +175,8 @@ Iso9660ArchiveFile::OpenStream(const char *pathname,
}
size_t
Iso9660InputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
Iso9660InputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
{
const
ScopeUnlock
unlock
(
mutex
);
...
...
src/archive/plugins/ZzipArchivePlugin.cxx
View file @
1b5c1f75
...
...
@@ -111,8 +111,9 @@ public:
/* virtual methods from InputStream */
bool
IsEOF
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
};
InputStreamPtr
...
...
@@ -130,7 +131,7 @@ ZzipArchiveFile::OpenStream(const char *pathname,
}
size_t
ZzipInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
ZzipInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
{
const
ScopeUnlock
unlock
(
mutex
);
...
...
@@ -149,7 +150,7 @@ ZzipInputStream::IsEOF() noexcept
}
void
ZzipInputStream
::
Seek
(
offset_type
new_offset
)
ZzipInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
new_offset
)
{
const
ScopeUnlock
unlock
(
mutex
);
...
...
src/command/FileCommands.cxx
View file @
1b5c1f75
...
...
@@ -292,9 +292,9 @@ read_stream_art(Response &r, const char *uri, size_t offset)
size_t
read_size
;
{
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
is
->
Seek
(
offset
);
read_size
=
is
->
Read
(
&
buffer
,
CHUNK_SIZE
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
is
->
Seek
(
lock
,
offset
);
read_size
=
is
->
Read
(
lock
,
&
buffer
,
CHUNK_SIZE
);
}
r
.
Format
(
"size: %"
PRIoffset
"
\n
"
...
...
src/command/FingerprintCommands.cxx
View file @
1b5c1f75
...
...
@@ -305,7 +305,7 @@ GetChromaprintCommand::Read(InputStream &is, void *buffer, size_t length)
cond
.
wait
(
lock
);
}
return
is
.
Read
(
buffer
,
length
);
return
is
.
Read
(
lock
,
buffer
,
length
);
}
CommandResult
...
...
src/decoder/Bridge.cxx
View file @
1b5c1f75
...
...
@@ -403,7 +403,7 @@ try {
dc
.
cond
.
wait
(
lock
);
}
size_t
nbytes
=
is
.
Read
(
buffer
,
length
);
size_t
nbytes
=
is
.
Read
(
lock
,
buffer
,
length
);
assert
(
nbytes
>
0
||
is
.
IsEOF
());
return
nbytes
;
...
...
src/decoder/Thread.cxx
View file @
1b5c1f75
...
...
@@ -55,7 +55,8 @@ static constexpr Domain decoder_thread_domain("decoder_thread");
static
bool
decoder_stream_decode
(
const
DecoderPlugin
&
plugin
,
DecoderBridge
&
bridge
,
InputStream
&
input_stream
)
InputStream
&
input_stream
,
std
::
unique_lock
<
Mutex
>
&
lock
)
{
assert
(
plugin
.
stream_decode
!=
nullptr
);
assert
(
bridge
.
stream_tag
==
nullptr
);
...
...
@@ -70,7 +71,7 @@ decoder_stream_decode(const DecoderPlugin &plugin,
/* rewind the stream, so each plugin gets a fresh start */
try
{
input_stream
.
Rewind
();
input_stream
.
Rewind
(
lock
);
}
catch
(...)
{
}
...
...
@@ -161,6 +162,7 @@ decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
static
bool
decoder_run_stream_plugin
(
DecoderBridge
&
bridge
,
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
,
const
char
*
suffix
,
const
DecoderPlugin
&
plugin
,
bool
&
tried_r
)
...
...
@@ -171,11 +173,12 @@ decoder_run_stream_plugin(DecoderBridge &bridge, InputStream &is,
bridge
.
Reset
();
tried_r
=
true
;
return
decoder_stream_decode
(
plugin
,
bridge
,
is
);
return
decoder_stream_decode
(
plugin
,
bridge
,
is
,
lock
);
}
static
bool
decoder_run_stream_locked
(
DecoderBridge
&
bridge
,
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
,
const
char
*
uri
,
bool
&
tried_r
)
{
UriSuffixBuffer
suffix_buffer
;
...
...
@@ -183,7 +186,8 @@ decoder_run_stream_locked(DecoderBridge &bridge, InputStream &is,
using
namespace
std
::
placeholders
;
const
auto
f
=
std
::
bind
(
decoder_run_stream_plugin
,
std
::
ref
(
bridge
),
std
::
ref
(
is
),
suffix
,
std
::
ref
(
bridge
),
std
::
ref
(
is
),
std
::
ref
(
lock
),
suffix
,
_1
,
std
::
ref
(
tried_r
));
return
decoder_plugins_try
(
f
);
}
...
...
@@ -192,7 +196,8 @@ decoder_run_stream_locked(DecoderBridge &bridge, InputStream &is,
* Try decoding a stream, using the fallback plugin.
*/
static
bool
decoder_run_stream_fallback
(
DecoderBridge
&
bridge
,
InputStream
&
is
)
decoder_run_stream_fallback
(
DecoderBridge
&
bridge
,
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
{
const
struct
DecoderPlugin
*
plugin
;
...
...
@@ -202,7 +207,7 @@ decoder_run_stream_fallback(DecoderBridge &bridge, InputStream &is)
plugin
=
decoder_plugin_from_name
(
"mad"
);
#endif
return
plugin
!=
nullptr
&&
plugin
->
stream_decode
!=
nullptr
&&
decoder_stream_decode
(
*
plugin
,
bridge
,
is
);
decoder_stream_decode
(
*
plugin
,
bridge
,
is
,
lock
);
}
/**
...
...
@@ -249,16 +254,16 @@ decoder_run_stream(DecoderBridge &bridge, const char *uri)
MaybeLoadReplayGain
(
bridge
,
*
input_stream
);
const
std
::
lock_guard
<
Mutex
>
protect
(
dc
.
mutex
);
std
::
unique_lock
<
Mutex
>
lock
(
dc
.
mutex
);
bool
tried
=
false
;
return
dc
.
command
==
DecoderCommand
::
STOP
||
decoder_run_stream_locked
(
bridge
,
*
input_stream
,
uri
,
decoder_run_stream_locked
(
bridge
,
*
input_stream
,
lock
,
uri
,
tried
)
||
/* fallback to mp3: this is needed for bastard streams
that don't have a suffix or set the mimeType */
(
!
tried
&&
decoder_run_stream_fallback
(
bridge
,
*
input_stream
));
decoder_run_stream_fallback
(
bridge
,
*
input_stream
,
lock
));
}
/**
...
...
@@ -282,8 +287,9 @@ TryDecoderFile(DecoderBridge &bridge, Path path_fs, const char *suffix,
const
std
::
lock_guard
<
Mutex
>
protect
(
dc
.
mutex
);
return
decoder_file_decode
(
plugin
,
bridge
,
path_fs
);
}
else
if
(
plugin
.
stream_decode
!=
nullptr
)
{
const
std
::
lock_guard
<
Mutex
>
protect
(
dc
.
mutex
);
return
decoder_stream_decode
(
plugin
,
bridge
,
input_stream
);
std
::
unique_lock
<
Mutex
>
lock
(
dc
.
mutex
);
return
decoder_stream_decode
(
plugin
,
bridge
,
input_stream
,
lock
);
}
else
return
false
;
}
...
...
src/input/AsyncInputStream.cxx
View file @
1b5c1f75
...
...
@@ -95,7 +95,8 @@ AsyncInputStream::IsEOF() noexcept
}
void
AsyncInputStream
::
Seek
(
offset_type
new_offset
)
AsyncInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
{
assert
(
IsReady
());
assert
(
seek_state
==
SeekState
::
NONE
);
...
...
@@ -136,7 +137,7 @@ AsyncInputStream::Seek(offset_type new_offset)
CondInputStreamHandler
cond_handler
;
const
ScopeExchangeInputStreamHandler
h
(
*
this
,
&
cond_handler
);
while
(
seek_state
!=
SeekState
::
NONE
)
cond_handler
.
cond
.
wait
(
mutex
);
cond_handler
.
cond
.
wait
(
lock
);
Check
();
}
...
...
@@ -171,7 +172,8 @@ AsyncInputStream::IsAvailable() noexcept
}
size_t
AsyncInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
AsyncInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
{
assert
(
!
GetEventLoop
().
IsInside
());
...
...
@@ -187,7 +189,7 @@ AsyncInputStream::Read(void *ptr, size_t read_size)
break
;
const
ScopeExchangeInputStreamHandler
h
(
*
this
,
&
cond_handler
);
cond_handler
.
cond
.
wait
(
mutex
);
cond_handler
.
cond
.
wait
(
lock
);
}
const
size_t
nbytes
=
std
::
min
(
read_size
,
r
.
size
);
...
...
src/input/AsyncInputStream.hxx
View file @
1b5c1f75
...
...
@@ -83,10 +83,12 @@ public:
/* virtual methods from InputStream */
void
Check
()
final
;
bool
IsEOF
()
noexcept
final
;
void
Seek
(
offset_type
new_offset
)
final
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
final
;
std
::
unique_ptr
<
Tag
>
ReadTag
()
noexcept
final
;
bool
IsAvailable
()
noexcept
final
;
size_t
Read
(
void
*
ptr
,
size_t
read_size
)
final
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
final
;
protected
:
/**
...
...
src/input/BufferedInputStream.cxx
View file @
1b5c1f75
...
...
@@ -64,7 +64,8 @@ BufferedInputStream::Check()
}
void
BufferedInputStream
::
Seek
(
offset_type
new_offset
)
BufferedInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
{
if
(
new_offset
>=
size
)
{
offset
=
size
;
...
...
@@ -84,7 +85,7 @@ BufferedInputStream::Seek(offset_type new_offset)
wake_cond
.
notify_one
();
while
(
seek
)
client_cond
.
wait
(
mutex
);
client_cond
.
wait
(
lock
);
if
(
seek_error
)
std
::
rethrow_exception
(
std
::
exchange
(
seek_error
,
{}));
...
...
@@ -105,7 +106,8 @@ BufferedInputStream::IsAvailable() noexcept
}
size_t
BufferedInputStream
::
Read
(
void
*
ptr
,
size_t
s
)
BufferedInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
s
)
{
if
(
offset
>=
size
)
return
0
;
...
...
@@ -140,7 +142,7 @@ BufferedInputStream::Read(void *ptr, size_t s)
wake_cond
.
notify_one
();
}
client_cond
.
wait
(
mutex
);
client_cond
.
wait
(
lock
);
}
}
...
...
@@ -156,7 +158,7 @@ BufferedInputStream::RunThread() noexcept
if
(
seek
)
{
try
{
input
->
Seek
(
seek_offset
);
input
->
Seek
(
lock
,
seek_offset
);
}
catch
(...)
{
seek_error
=
std
::
current_exception
();
}
...
...
@@ -183,7 +185,7 @@ BufferedInputStream::RunThread() noexcept
offset to prepare filling
the buffer from there */
try
{
input
->
Seek
(
offset
);
input
->
Seek
(
lock
,
offset
);
}
catch
(...)
{
read_error
=
std
::
current_exception
();
client_cond
.
notify_one
();
...
...
@@ -195,7 +197,8 @@ BufferedInputStream::RunThread() noexcept
}
try
{
size_t
nbytes
=
input
->
Read
(
w
.
data
,
w
.
size
);
size_t
nbytes
=
input
->
Read
(
lock
,
w
.
data
,
w
.
size
);
buffer
.
Commit
(
read_offset
,
read_offset
+
nbytes
);
}
catch
(...)
{
...
...
src/input/BufferedInputStream.hxx
View file @
1b5c1f75
...
...
@@ -85,12 +85,13 @@ public:
/* we don't need to implement Update() because all attributes
have been copied already in our constructor */
//void Update() noexcept;
void
Seek
(
offset_type
offset
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
bool
IsEOF
()
noexcept
override
;
/* we don't support tags */
// std::unique_ptr<Tag> ReadTag() override;
bool
IsAvailable
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
/* virtual methods from class InputStreamHandler */
void
OnInputStreamReady
()
noexcept
override
{
...
...
src/input/FailingInputStream.hxx
View file @
1b5c1f75
...
...
@@ -45,7 +45,7 @@ public:
std
::
rethrow_exception
(
error
);
}
void
Seek
(
offset_type
)
override
{
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
)
override
{
std
::
rethrow_exception
(
error
);
}
...
...
@@ -53,7 +53,7 @@ public:
return
false
;
}
size_t
Read
(
void
*
,
size_t
)
override
{
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
,
size_t
)
override
{
std
::
rethrow_exception
(
error
);
}
};
...
...
src/input/IcyInputStream.cxx
View file @
1b5c1f75
...
...
@@ -80,13 +80,14 @@ IcyInputStream::ReadTag() noexcept
}
size_t
IcyInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
IcyInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
{
if
(
!
IsEnabled
())
return
ProxyInputStream
::
Read
(
ptr
,
read_size
);
return
ProxyInputStream
::
Read
(
lock
,
ptr
,
read_size
);
while
(
true
)
{
size_t
nbytes
=
ProxyInputStream
::
Read
(
ptr
,
read_size
);
size_t
nbytes
=
ProxyInputStream
::
Read
(
lock
,
ptr
,
read_size
);
if
(
nbytes
==
0
)
return
0
;
...
...
src/input/IcyInputStream.hxx
View file @
1b5c1f75
...
...
@@ -66,7 +66,8 @@ public:
/* virtual methods from InputStream */
void
Update
()
noexcept
override
;
std
::
unique_ptr
<
Tag
>
ReadTag
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
};
#endif
src/input/InputStream.cxx
View file @
1b5c1f75
...
...
@@ -72,7 +72,7 @@ InputStream::CheapSeeking() const noexcept
}
void
InputStream
::
Seek
(
gcc_unused
offset_type
new_offset
)
InputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
gcc_unused
offset_type
new_offset
)
{
throw
std
::
runtime_error
(
"Seeking is not implemented"
);
}
...
...
@@ -80,15 +80,15 @@ InputStream::Seek(gcc_unused offset_type new_offset)
void
InputStream
::
LockSeek
(
offset_type
_offset
)
{
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
Seek
(
_offset
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
Seek
(
lock
,
_offset
);
}
void
InputStream
::
LockSkip
(
offset_type
_offset
)
{
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
Skip
(
_offset
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
Skip
(
lock
,
_offset
);
}
std
::
unique_ptr
<
Tag
>
...
...
@@ -119,18 +119,18 @@ InputStream::LockRead(void *ptr, size_t _size)
#endif
assert
(
_size
>
0
);
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
return
Read
(
ptr
,
_size
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
return
Read
(
lock
,
ptr
,
_size
);
}
void
InputStream
::
ReadFull
(
void
*
_ptr
,
size_t
_size
)
InputStream
::
ReadFull
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
_ptr
,
size_t
_size
)
{
uint8_t
*
ptr
=
(
uint8_t
*
)
_ptr
;
size_t
nbytes_total
=
0
;
while
(
_size
>
0
)
{
size_t
nbytes
=
Read
(
ptr
+
nbytes_total
,
_size
);
size_t
nbytes
=
Read
(
lock
,
ptr
+
nbytes_total
,
_size
);
if
(
nbytes
==
0
)
throw
std
::
runtime_error
(
"Unexpected end of file"
);
...
...
@@ -148,8 +148,8 @@ InputStream::LockReadFull(void *ptr, size_t _size)
#endif
assert
(
_size
>
0
);
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
ReadFull
(
ptr
,
_size
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
ReadFull
(
lock
,
ptr
,
_size
);
}
bool
...
...
src/input/InputStream.hxx
View file @
1b5c1f75
...
...
@@ -271,9 +271,11 @@ public:
*
* Throws std::runtime_error on error.
*
* @param lock the locked mutex; may be used to wait on
* condition variables
* @param offset the relative offset
*/
virtual
void
Seek
(
offset_type
offset
);
virtual
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
);
/**
* Wrapper for Seek() which locks and unlocks the mutex; the
...
...
@@ -285,8 +287,8 @@ public:
* Rewind to the beginning of the stream. This is a wrapper
* for Seek(0, error).
*/
void
Rewind
()
{
Seek
(
0
);
void
Rewind
(
std
::
unique_lock
<
Mutex
>
&
lock
)
{
Seek
(
lock
,
0
);
}
void
LockRewind
()
{
...
...
@@ -296,8 +298,9 @@ public:
/**
* Skip input bytes.
*/
void
Skip
(
offset_type
_offset
)
{
Seek
(
GetOffset
()
+
_offset
);
void
Skip
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
_offset
)
{
Seek
(
lock
,
GetOffset
()
+
_offset
);
}
void
LockSkip
(
offset_type
_offset
);
...
...
@@ -351,12 +354,15 @@ public:
*
* Throws std::runtime_error on error.
*
* @param lock the locked mutex; may be used to wait on
* condition variables
* @param ptr the buffer to read into
* @param size the maximum number of bytes to read
* @return the number of bytes read
*/
gcc_nonnull_all
virtual
size_t
Read
(
void
*
ptr
,
size_t
size
)
=
0
;
virtual
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
=
0
;
/**
* Wrapper for Read() which locks and unlocks the mutex;
...
...
@@ -379,7 +385,7 @@ public:
* @return true if the whole data was read, false otherwise.
*/
gcc_nonnull_all
void
ReadFull
(
void
*
ptr
,
size_t
size
);
void
ReadFull
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
);
/**
* Wrapper for ReadFull() which locks and unlocks the mutex;
...
...
src/input/ProxyInputStream.cxx
View file @
1b5c1f75
...
...
@@ -89,12 +89,13 @@ ProxyInputStream::Update() noexcept
}
void
ProxyInputStream
::
Seek
(
offset_type
new_offset
)
ProxyInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
{
while
(
!
input
)
set_input_cond
.
wait
(
mutex
);
set_input_cond
.
wait
(
lock
);
input
->
Seek
(
new_offset
);
input
->
Seek
(
lock
,
new_offset
);
CopyAttributes
();
}
...
...
@@ -120,12 +121,13 @@ ProxyInputStream::IsAvailable() noexcept
}
size_t
ProxyInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
ProxyInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
{
while
(
!
input
)
set_input_cond
.
wait
(
mutex
);
set_input_cond
.
wait
(
lock
);
size_t
nbytes
=
input
->
Read
(
ptr
,
read_size
);
size_t
nbytes
=
input
->
Read
(
lock
,
ptr
,
read_size
);
CopyAttributes
();
return
nbytes
;
}
src/input/ProxyInputStream.hxx
View file @
1b5c1f75
...
...
@@ -60,11 +60,13 @@ public:
/* virtual methods from InputStream */
void
Check
()
override
;
void
Update
()
noexcept
override
;
void
Seek
(
offset_type
new_offset
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
override
;
bool
IsEOF
()
noexcept
override
;
std
::
unique_ptr
<
Tag
>
ReadTag
()
noexcept
override
;
bool
IsAvailable
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
read_size
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
override
;
protected
:
/**
...
...
src/input/RewindInputStream.cxx
View file @
1b5c1f75
...
...
@@ -60,8 +60,9 @@ public:
return
!
ReadingFromBuffer
()
&&
ProxyInputStream
::
IsEOF
();
}
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
private
:
/**
...
...
@@ -74,7 +75,8 @@ private:
};
size_t
RewindInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
RewindInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
{
if
(
ReadingFromBuffer
())
{
/* buffered read */
...
...
@@ -93,7 +95,7 @@ RewindInputStream::Read(void *ptr, size_t read_size)
}
else
{
/* pass method call to underlying stream */
size_t
nbytes
=
input
->
Read
(
ptr
,
read_size
);
size_t
nbytes
=
input
->
Read
(
lock
,
ptr
,
read_size
);
if
(
input
->
GetOffset
()
>
(
offset_type
)
sizeof
(
buffer
))
/* disable buffering */
...
...
@@ -114,7 +116,7 @@ RewindInputStream::Read(void *ptr, size_t read_size)
}
void
RewindInputStream
::
Seek
(
offset_type
new_offset
)
RewindInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
new_offset
)
{
assert
(
IsReady
());
...
...
@@ -132,7 +134,7 @@ RewindInputStream::Seek(offset_type new_offset)
buffered range now */
tail
=
0
;
ProxyInputStream
::
Seek
(
new_offset
);
ProxyInputStream
::
Seek
(
lock
,
new_offset
);
}
}
...
...
src/input/ThreadInputStream.cxx
View file @
1b5c1f75
...
...
@@ -130,7 +130,8 @@ ThreadInputStream::IsAvailable() noexcept
}
inline
size_t
ThreadInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
ThreadInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
read_size
)
{
assert
(
!
thread
.
IsInside
());
...
...
@@ -154,7 +155,7 @@ ThreadInputStream::Read(void *ptr, size_t read_size)
return
0
;
const
ScopeExchangeInputStreamHandler
h
(
*
this
,
&
cond_handler
);
cond_handler
.
cond
.
wait
(
mutex
);
cond_handler
.
cond
.
wait
(
lock
);
}
}
...
...
src/input/ThreadInputStream.hxx
View file @
1b5c1f75
...
...
@@ -94,7 +94,8 @@ public:
void
Check
()
override
final
;
bool
IsEOF
()
noexcept
final
;
bool
IsAvailable
()
noexcept
final
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
final
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
final
;
protected
:
/**
...
...
src/input/plugins/CdioParanoiaInputPlugin.cxx
View file @
1b5c1f75
...
...
@@ -91,8 +91,9 @@ class CdioParanoiaInputStream final : public InputStream {
/* virtual methods from InputStream */
bool
IsEOF
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
};
static
constexpr
Domain
cdio_domain
(
"cdio"
);
...
...
@@ -255,7 +256,8 @@ input_cdio_open(const char *uri,
}
void
CdioParanoiaInputStream
::
Seek
(
offset_type
new_offset
)
CdioParanoiaInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
new_offset
)
{
if
(
new_offset
>
size
)
throw
FormatRuntimeError
(
"Invalid offset to seek %ld (%ld)"
,
...
...
@@ -276,7 +278,8 @@ CdioParanoiaInputStream::Seek(offset_type new_offset)
}
size_t
CdioParanoiaInputStream
::
Read
(
void
*
ptr
,
size_t
length
)
CdioParanoiaInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
length
)
{
size_t
nbytes
=
0
;
char
*
wptr
=
(
char
*
)
ptr
;
...
...
src/input/plugins/FfmpegInputPlugin.cxx
View file @
1b5c1f75
...
...
@@ -49,8 +49,10 @@ public:
/* virtual methods from InputStream */
bool
IsEOF
()
noexcept
override
;
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
};
gcc_const
...
...
@@ -79,7 +81,8 @@ input_ffmpeg_open(const char *uri,
}
size_t
FfmpegInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
FfmpegInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
{
size_t
result
;
...
...
@@ -99,7 +102,7 @@ FfmpegInputStream::IsEOF() noexcept
}
void
FfmpegInputStream
::
Seek
(
offset_type
new_offset
)
FfmpegInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
new_offset
)
{
uint64_t
result
;
...
...
src/input/plugins/FileInputPlugin.cxx
View file @
1b5c1f75
...
...
@@ -48,8 +48,10 @@ public:
return
GetOffset
()
>=
GetSize
();
}
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
};
InputStreamPtr
...
...
@@ -74,7 +76,8 @@ OpenFileInputStream(Path path, Mutex &mutex)
}
void
FileInputStream
::
Seek
(
offset_type
new_offset
)
FileInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
new_offset
)
{
{
const
ScopeUnlock
unlock
(
mutex
);
...
...
@@ -85,7 +88,8 @@ FileInputStream::Seek(offset_type new_offset)
}
size_t
FileInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
FileInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
{
size_t
nbytes
;
...
...
src/input/plugins/SmbclientInputPlugin.cxx
View file @
1b5c1f75
...
...
@@ -56,8 +56,9 @@ public:
return
offset
>=
size
;
}
size_t
Read
(
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
offset_type
offset
)
override
;
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
lock
,
void
*
ptr
,
size_t
size
)
override
;
void
Seek
(
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
override
;
};
/*
...
...
@@ -118,7 +119,8 @@ input_smbclient_open(const char *uri,
}
size_t
SmbclientInputStream
::
Read
(
void
*
ptr
,
size_t
read_size
)
SmbclientInputStream
::
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
{
ssize_t
nbytes
;
...
...
@@ -136,7 +138,8 @@ SmbclientInputStream::Read(void *ptr, size_t read_size)
}
void
SmbclientInputStream
::
Seek
(
offset_type
new_offset
)
SmbclientInputStream
::
Seek
(
std
::
unique_lock
<
Mutex
>
&
,
offset_type
new_offset
)
{
off_t
result
;
...
...
src/tag/Aiff.cxx
View file @
1b5c1f75
...
...
@@ -39,14 +39,14 @@ struct aiff_chunk_header {
};
size_t
aiff_seek_id3
(
InputStream
&
is
)
aiff_seek_id3
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
{
/* seek to the beginning and read the AIFF header */
is
.
Rewind
();
is
.
Rewind
(
lock
);
aiff_header
header
;
is
.
ReadFull
(
&
header
,
sizeof
(
header
));
is
.
ReadFull
(
lock
,
&
header
,
sizeof
(
header
));
if
(
memcmp
(
header
.
id
,
"FORM"
,
4
)
!=
0
||
(
is
.
KnownSize
()
&&
FromBE32
(
header
.
size
)
>
is
.
GetSize
())
||
(
memcmp
(
header
.
format
,
"AIFF"
,
4
)
!=
0
&&
...
...
@@ -57,7 +57,7 @@ aiff_seek_id3(InputStream &is)
/* read the chunk header */
aiff_chunk_header
chunk
;
is
.
ReadFull
(
&
chunk
,
sizeof
(
chunk
));
is
.
ReadFull
(
lock
,
&
chunk
,
sizeof
(
chunk
));
size_t
size
=
FromBE32
(
chunk
.
size
);
if
(
size
>
size_t
(
std
::
numeric_limits
<
int
>::
max
()))
...
...
@@ -73,6 +73,6 @@ aiff_seek_id3(InputStream &is)
/* pad byte */
++
size
;
is
.
Skip
(
size
);
is
.
Skip
(
lock
,
size
);
}
}
src/tag/Aiff.hxx
View file @
1b5c1f75
...
...
@@ -25,9 +25,12 @@
#ifndef MPD_AIFF_HXX
#define MPD_AIFF_HXX
#include <mutex>
#include <stddef.h>
class
InputStream
;
class
Mutex
;
/**
* Seeks the AIFF file to the ID3 chunk.
...
...
@@ -38,6 +41,6 @@ class InputStream;
* @return the size of the ID3 chunk
*/
size_t
aiff_seek_id3
(
InputStream
&
is
);
aiff_seek_id3
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
);
#endif
src/tag/ApeLoader.cxx
View file @
1b5c1f75
...
...
@@ -40,15 +40,15 @@ struct ApeFooter {
bool
tag_ape_scan
(
InputStream
&
is
,
ApeTagCallback
callback
)
try
{
const
std
::
lock_guard
<
Mutex
>
protect
(
is
.
mutex
);
std
::
unique_lock
<
Mutex
>
lock
(
is
.
mutex
);
if
(
!
is
.
KnownSize
()
||
!
is
.
CheapSeeking
())
return
false
;
/* determine if file has an apeV2 tag */
ApeFooter
footer
;
is
.
Seek
(
is
.
GetSize
()
-
sizeof
(
footer
));
is
.
ReadFull
(
&
footer
,
sizeof
(
footer
));
is
.
Seek
(
lock
,
is
.
GetSize
()
-
sizeof
(
footer
));
is
.
ReadFull
(
lock
,
&
footer
,
sizeof
(
footer
));
if
(
memcmp
(
footer
.
id
,
"APETAGEX"
,
sizeof
(
footer
.
id
))
!=
0
||
FromLE32
(
footer
.
version
)
!=
2000
)
...
...
@@ -61,14 +61,14 @@ try {
remaining
>
1024
*
1024
)
return
false
;
is
.
Seek
(
is
.
GetSize
()
-
remaining
);
is
.
Seek
(
lock
,
is
.
GetSize
()
-
remaining
);
/* read tag into buffer */
remaining
-=
sizeof
(
footer
);
assert
(
remaining
>
10
);
std
::
unique_ptr
<
char
[]
>
buffer
(
new
char
[
remaining
]);
is
.
ReadFull
(
buffer
.
get
(),
remaining
);
is
.
ReadFull
(
lock
,
buffer
.
get
(),
remaining
);
/* read tags */
unsigned
n
=
FromLE32
(
footer
.
count
);
...
...
src/tag/Id3Load.cxx
View file @
1b5c1f75
...
...
@@ -37,11 +37,12 @@ tag_is_id3v1(struct id3_tag *tag) noexcept
}
static
long
get_id3v2_footer_size
(
InputStream
&
is
,
offset_type
offset
)
get_id3v2_footer_size
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
try
{
id3_byte_t
buf
[
ID3_TAG_QUERYSIZE
];
is
.
Seek
(
offset
);
is
.
ReadFull
(
buf
,
sizeof
(
buf
));
is
.
Seek
(
lock
,
offset
);
is
.
ReadFull
(
lock
,
buf
,
sizeof
(
buf
));
return
id3_tag_query
(
buf
,
sizeof
(
buf
));
}
catch
(...)
{
...
...
@@ -49,10 +50,10 @@ try {
}
static
UniqueId3Tag
ReadId3Tag
(
InputStream
&
is
)
ReadId3Tag
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
try
{
id3_byte_t
query_buffer
[
ID3_TAG_QUERYSIZE
];
is
.
ReadFull
(
query_buffer
,
sizeof
(
query_buffer
));
is
.
ReadFull
(
lock
,
query_buffer
,
sizeof
(
query_buffer
));
/* Look for a tag header */
long
tag_size
=
id3_tag_query
(
query_buffer
,
sizeof
(
query_buffer
));
...
...
@@ -72,7 +73,7 @@ try {
/* now read the remaining bytes */
const
size_t
remaining
=
tag_size
-
sizeof
(
query_buffer
);
is
.
ReadFull
(
end
,
remaining
);
is
.
ReadFull
(
lock
,
end
,
remaining
);
return
UniqueId3Tag
(
id3_tag_parse
(
tag_buffer
.
get
(),
tag_size
));
}
catch
(...)
{
...
...
@@ -80,20 +81,20 @@ try {
}
static
UniqueId3Tag
ReadId3Tag
(
InputStream
&
is
,
offset_type
offset
)
ReadId3Tag
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
try
{
is
.
Seek
(
offset
);
is
.
Seek
(
lock
,
offset
);
return
ReadId3Tag
(
is
);
return
ReadId3Tag
(
is
,
lock
);
}
catch
(...)
{
return
nullptr
;
}
static
UniqueId3Tag
ReadId3v1Tag
(
InputStream
&
is
)
ReadId3v1Tag
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
try
{
id3_byte_t
buffer
[
ID3V1_SIZE
];
is
.
ReadFull
(
buffer
,
ID3V1_SIZE
);
is
.
ReadFull
(
lock
,
buffer
,
ID3V1_SIZE
);
return
UniqueId3Tag
(
id3_tag_parse
(
buffer
,
ID3V1_SIZE
));
}
catch
(...)
{
...
...
@@ -101,18 +102,19 @@ try {
}
static
UniqueId3Tag
ReadId3v1Tag
(
InputStream
&
is
,
offset_type
offset
)
ReadId3v1Tag
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
,
offset_type
offset
)
try
{
is
.
Seek
(
offset
);
return
ReadId3v1Tag
(
is
);
is
.
Seek
(
lock
,
offset
);
return
ReadId3v1Tag
(
is
,
lock
);
}
catch
(...)
{
return
nullptr
;
}
static
UniqueId3Tag
tag_id3_find_from_beginning
(
InputStream
&
is
)
tag_id3_find_from_beginning
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
try
{
auto
tag
=
ReadId3Tag
(
is
);
auto
tag
=
ReadId3Tag
(
is
,
lock
);
if
(
!
tag
)
{
return
nullptr
;
}
else
if
(
tag_is_id3v1
(
tag
.
get
()))
{
...
...
@@ -129,7 +131,7 @@ try {
break
;
/* Get the tag specified by the SEEK frame */
auto
seektag
=
ReadId3Tag
(
is
,
is
.
GetOffset
()
+
seek
);
auto
seektag
=
ReadId3Tag
(
is
,
lock
,
is
.
GetOffset
()
+
seek
);
if
(
!
seektag
||
tag_is_id3v1
(
seektag
.
get
()))
break
;
...
...
@@ -143,7 +145,7 @@ try {
}
static
UniqueId3Tag
tag_id3_find_from_end
(
InputStream
&
is
)
tag_id3_find_from_end
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
try
{
if
(
!
is
.
KnownSize
()
||
!
is
.
CheapSeeking
())
return
nullptr
;
...
...
@@ -155,7 +157,7 @@ try {
offset_type
offset
=
size
-
ID3V1_SIZE
;
/* Get an id3v1 tag from the end of file for later use */
auto
v1tag
=
ReadId3v1Tag
(
is
,
offset
);
auto
v1tag
=
ReadId3v1Tag
(
is
,
lock
,
offset
);
if
(
!
v1tag
)
offset
=
size
;
...
...
@@ -164,7 +166,7 @@ try {
return
v1tag
;
long
tag_offset
=
get_id3v2_footer_size
(
is
,
offset
-
ID3_TAG_QUERYSIZE
);
get_id3v2_footer_size
(
is
,
lock
,
offset
-
ID3_TAG_QUERYSIZE
);
if
(
tag_offset
>=
0
)
return
v1tag
;
...
...
@@ -173,7 +175,7 @@ try {
return
v1tag
;
/* Get the tag which the footer belongs to */
auto
tag
=
ReadId3Tag
(
is
,
offset
-
tag_size
);
auto
tag
=
ReadId3Tag
(
is
,
lock
,
offset
-
tag_size
);
if
(
!
tag
)
return
v1tag
;
...
...
@@ -184,13 +186,13 @@ try {
}
static
UniqueId3Tag
tag_id3_riff_aiff_load
(
InputStream
&
is
)
tag_id3_riff_aiff_load
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
try
{
size_t
size
;
try
{
size
=
riff_seek_id3
(
is
);
size
=
riff_seek_id3
(
is
,
lock
);
}
catch
(...)
{
size
=
aiff_seek_id3
(
is
);
size
=
aiff_seek_id3
(
is
,
lock
);
}
if
(
size
>
4
*
1024
*
1024
)
...
...
@@ -198,7 +200,7 @@ try {
return
nullptr
;
std
::
unique_ptr
<
id3_byte_t
[]
>
buffer
(
new
id3_byte_t
[
size
]);
is
.
ReadFull
(
buffer
.
get
(),
size
);
is
.
ReadFull
(
lock
,
buffer
.
get
(),
size
);
return
UniqueId3Tag
(
id3_tag_parse
(
buffer
.
get
(),
size
));
}
catch
(...)
{
...
...
@@ -208,13 +210,13 @@ try {
UniqueId3Tag
tag_id3_load
(
InputStream
&
is
)
try
{
const
std
::
lock_guard
<
Mutex
>
protect
(
is
.
mutex
);
std
::
unique_lock
<
Mutex
>
lock
(
is
.
mutex
);
auto
tag
=
tag_id3_find_from_beginning
(
is
);
auto
tag
=
tag_id3_find_from_beginning
(
is
,
lock
);
if
(
tag
==
nullptr
&&
is
.
CheapSeeking
())
{
tag
=
tag_id3_riff_aiff_load
(
is
);
tag
=
tag_id3_riff_aiff_load
(
is
,
lock
);
if
(
tag
==
nullptr
)
tag
=
tag_id3_find_from_end
(
is
);
tag
=
tag_id3_find_from_end
(
is
,
lock
);
}
return
tag
;
...
...
src/tag/Riff.cxx
View file @
1b5c1f75
...
...
@@ -39,14 +39,14 @@ struct riff_chunk_header {
};
size_t
riff_seek_id3
(
InputStream
&
is
)
riff_seek_id3
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
)
{
/* seek to the beginning and read the RIFF header */
is
.
Rewind
();
is
.
Rewind
(
lock
);
riff_header
header
;
is
.
ReadFull
(
&
header
,
sizeof
(
header
));
is
.
ReadFull
(
lock
,
&
header
,
sizeof
(
header
));
if
(
memcmp
(
header
.
id
,
"RIFF"
,
4
)
!=
0
||
(
is
.
KnownSize
()
&&
FromLE32
(
header
.
size
)
>
is
.
GetSize
()))
throw
std
::
runtime_error
(
"Not a RIFF file"
);
...
...
@@ -55,7 +55,7 @@ riff_seek_id3(InputStream &is)
/* read the chunk header */
riff_chunk_header
chunk
;
is
.
ReadFull
(
&
chunk
,
sizeof
(
chunk
));
is
.
ReadFull
(
lock
,
&
chunk
,
sizeof
(
chunk
));
size_t
size
=
FromLE32
(
chunk
.
size
);
if
(
size
>
size_t
(
std
::
numeric_limits
<
int
>::
max
()))
...
...
@@ -72,6 +72,6 @@ riff_seek_id3(InputStream &is)
/* pad byte */
++
size
;
is
.
Skip
(
size
);
is
.
Skip
(
lock
,
size
);
}
}
src/tag/Riff.hxx
View file @
1b5c1f75
...
...
@@ -25,8 +25,11 @@
#ifndef MPD_RIFF_HXX
#define MPD_RIFF_HXX
#include <mutex>
#include <stddef.h>
class
Mutex
;
class
InputStream
;
/**
...
...
@@ -38,6 +41,6 @@ class InputStream;
* @return the size of the ID3 chunk
*/
size_t
riff_seek_id3
(
InputStream
&
is
);
riff_seek_id3
(
InputStream
&
is
,
std
::
unique_lock
<
Mutex
>
&
lock
);
#endif
test/TestRewindInputStream.cxx
View file @
1b5c1f75
...
...
@@ -28,7 +28,8 @@ public:
return
remaining
==
0
;
}
size_t
Read
(
void
*
ptr
,
size_t
read_size
)
override
{
size_t
Read
(
std
::
unique_lock
<
Mutex
>
&
,
void
*
ptr
,
size_t
read_size
)
override
{
size_t
nbytes
=
std
::
min
(
remaining
,
read_size
);
memcpy
(
ptr
,
data
,
nbytes
);
data
+=
nbytes
;
...
...
@@ -51,7 +52,7 @@ TEST(RewindInputStream, Basic)
EXPECT_TRUE
(
ris
.
get
()
!=
sis
);
EXPECT_TRUE
(
ris
!=
nullptr
);
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
ris
->
Update
();
EXPECT_TRUE
(
ris
->
IsReady
());
...
...
@@ -59,50 +60,50 @@ TEST(RewindInputStream, Basic)
EXPECT_EQ
(
offset_type
(
0
),
ris
->
GetOffset
());
char
buffer
[
16
];
size_t
nbytes
=
ris
->
Read
(
buffer
,
2
);
size_t
nbytes
=
ris
->
Read
(
lock
,
buffer
,
2
);
EXPECT_EQ
(
size_t
(
2
),
nbytes
);
EXPECT_EQ
(
'f'
,
buffer
[
0
]);
EXPECT_EQ
(
'o'
,
buffer
[
1
]);
EXPECT_EQ
(
offset_type
(
2
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
2
);
nbytes
=
ris
->
Read
(
lock
,
buffer
,
2
);
EXPECT_EQ
(
size_t
(
2
),
nbytes
);
EXPECT_EQ
(
'o'
,
buffer
[
0
]);
EXPECT_EQ
(
' '
,
buffer
[
1
]);
EXPECT_EQ
(
offset_type
(
4
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
ris
->
Seek
(
1
);
ris
->
Seek
(
lock
,
1
);
EXPECT_EQ
(
offset_type
(
1
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
2
);
nbytes
=
ris
->
Read
(
lock
,
buffer
,
2
);
EXPECT_EQ
(
size_t
(
2
),
nbytes
);
EXPECT_EQ
(
'o'
,
buffer
[
0
]);
EXPECT_EQ
(
'o'
,
buffer
[
1
]);
EXPECT_EQ
(
offset_type
(
3
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
ris
->
Seek
(
0
);
ris
->
Seek
(
lock
,
0
);
EXPECT_EQ
(
offset_type
(
0
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
2
);
nbytes
=
ris
->
Read
(
lock
,
buffer
,
2
);
EXPECT_EQ
(
size_t
(
2
),
nbytes
);
EXPECT_EQ
(
'f'
,
buffer
[
0
]);
EXPECT_EQ
(
'o'
,
buffer
[
1
]);
EXPECT_EQ
(
offset_type
(
2
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
sizeof
(
buffer
));
nbytes
=
ris
->
Read
(
lock
,
buffer
,
sizeof
(
buffer
));
EXPECT_EQ
(
size_t
(
2
),
nbytes
);
EXPECT_EQ
(
'o'
,
buffer
[
0
]);
EXPECT_EQ
(
' '
,
buffer
[
1
]);
EXPECT_EQ
(
offset_type
(
4
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
sizeof
(
buffer
));
nbytes
=
ris
->
Read
(
lock
,
buffer
,
sizeof
(
buffer
));
EXPECT_EQ
(
size_t
(
3
),
nbytes
);
EXPECT_EQ
(
'b'
,
buffer
[
0
]);
EXPECT_EQ
(
'a'
,
buffer
[
1
]);
...
...
@@ -110,11 +111,11 @@ TEST(RewindInputStream, Basic)
EXPECT_EQ
(
offset_type
(
7
),
ris
->
GetOffset
());
EXPECT_TRUE
(
ris
->
IsEOF
());
ris
->
Seek
(
3
);
ris
->
Seek
(
lock
,
3
);
EXPECT_EQ
(
offset_type
(
3
),
ris
->
GetOffset
());
EXPECT_FALSE
(
ris
->
IsEOF
());
nbytes
=
ris
->
Read
(
buffer
,
sizeof
(
buffer
));
nbytes
=
ris
->
Read
(
lock
,
buffer
,
sizeof
(
buffer
));
EXPECT_EQ
(
size_t
(
4
),
nbytes
);
EXPECT_EQ
(
' '
,
buffer
[
0
]);
EXPECT_EQ
(
'b'
,
buffer
[
1
]);
...
...
test/run_input.cxx
View file @
1b5c1f75
...
...
@@ -131,7 +131,7 @@ tag_save(FILE *file, const Tag &tag)
static
int
dump_input_stream
(
InputStream
*
is
)
{
const
std
::
lock_guard
<
Mutex
>
protect
(
is
->
mutex
);
std
::
unique_lock
<
Mutex
>
lock
(
is
->
mutex
);
/* print meta data */
...
...
@@ -150,7 +150,7 @@ dump_input_stream(InputStream *is)
}
char
buffer
[
4096
];
size_t
num_read
=
is
->
Read
(
buffer
,
sizeof
(
buffer
));
size_t
num_read
=
is
->
Read
(
lock
,
buffer
,
sizeof
(
buffer
));
if
(
num_read
==
0
)
break
;
...
...
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