Compare commits

...

38 Commits

Author SHA1 Message Date
Max Kellermann
57e0cc5442 release v0.18.5 2013-11-23 18:30:12 +01:00
Max Kellermann
73f45d87d5 decoder/{dsf,dsdiff}: eliminate useless assignments 2013-11-23 18:30:12 +01:00
Max Kellermann
ae88ba986e archive/iso9660: eliminate useless assignments 2013-11-23 18:30:12 +01:00
Max Kellermann
d6247902ec input/curl: work around stream resume bug (fixed in libcurl 7.32.0) 2013-11-23 12:13:41 +01:00
Max Kellermann
a566c28a49 input/curl: add global variable "curl_version" 2013-11-23 12:08:46 +01:00
Max Kellermann
2eddb63a83 input/curl: dump version number 2013-11-23 12:02:39 +01:00
Max Kellermann
fc7d5b055d PcmResampleLibsamplerate: clip 24 bit data
Using pcm_resample_lsr_32() for 24 bit samples works, but may cause 24
bit overflows.  This commit makes 24 bit a special case with explicit
clipping.
2013-11-22 23:27:56 +01:00
Max Kellermann
87c8953e8e PcmResample: un-inline Resample24() 2013-11-22 23:24:40 +01:00
Max Kellermann
45d27a52f1 PcmUtils: add function PcmClampN() 2013-11-22 23:24:40 +01:00
Max Kellermann
d22acc59c9 db/proxy: implement method GetUpdateStamp() 2013-11-22 00:45:27 +01:00
Max Kellermann
c064e8d62f DatabasePlugin: add method GetUpdateStamp()
Refactor SimpleDatabase::GetLastModified() to be generic for all
plugins.  Remove the SimpleDatabase assumption from db_stats_print(),
allowing it to be implemented by all database plugins.
2013-11-22 00:35:29 +01:00
Max Kellermann
099a2cb586 Stats: print db statistics only if db is available
Fixes crash on "stats" in certain configurations.
2013-11-22 00:27:37 +01:00
Max Kellermann
042fe2a9d0 Stats: print more unsigned integers 2013-11-22 00:23:27 +01:00
Max Kellermann
ff1c1107f3 Stats: auto-reload statistics with proxy plugin 2013-11-22 00:19:28 +01:00
Max Kellermann
41a3fd0fd0 Stats: use struct DatabaseStats
Eliminate redundant declaration.
2013-11-22 00:12:12 +01:00
Max Kellermann
b9169a5670 Stats: move the GTimer variable out of struct stats 2013-11-22 00:10:53 +01:00
Max Kellermann
2ecd5fa28d Stats: don't export the global variable "stats"
Unused outside of Stats.cxx.
2013-11-22 00:08:43 +01:00
Max Kellermann
e719b6cc41 Stats: print db_update as unsigned integer 2013-11-22 00:04:58 +01:00
Max Kellermann
67b8124a1d Mapper: _get_music_directory_utf8() may return nullptr
If no music_directory is configured, return nullptr instead of an
empty string.  This fixes a crash when db_file is configured without
music_directory.
2013-11-22 00:02:17 +01:00
Florian Schlichting
51ec499c89 system/ByteOrder: testing for endianness in a more general way
Fixes build tests on ia64 and mipsel by testing for endianness in a
more general / portable way.
2013-11-21 23:04:49 +01:00
Max Kellermann
3a4df25db2 util/ByteOrder: add comments 2013-11-21 23:04:31 +01:00
Max Kellermann
37cf78ef45 util/ByteOrder: indent the preprocessor directives
Improve readability.
2013-11-21 23:03:28 +01:00
Max Kellermann
727c622659 configure.ac: auto-detect fluidsynth by default
The option "--enable-fluidsynth" was documented to be "auto" by
default, when it was really "no".
2013-11-21 22:50:58 +01:00
Max Kellermann
74a778e65f configure.ac: prepare for 0.18.5 2013-11-18 20:03:30 +01:00
Denis Krjuchkov
1fc0c9fe8a NEWS: add version 0.18.5 change log 2013-11-18 16:40:00 +06:00
Denis Krjuchkov
740d8ec5ab system/fd_util.h: avoid symbol conflict with statically linked libmpdclient 2013-11-18 16:35:22 +06:00
Denis Krjuchkov
0bcc477d46 decoder/OggFind.cxx: include stdio.h for SEEK_END definition 2013-11-18 16:28:39 +06:00
Max Kellermann
35297f8d4f release v0.18.4 2013-11-13 18:26:01 +01:00
Max Kellermann
6f4202408c doc/example: remove "format" and "audio_output_format"
Just an attempt to prevent users from shooting themselves in the foot
by uncommenting these lines without knowing what they're doing.
2013-11-11 17:18:29 +01:00
Max Kellermann
0b6548a282 util/RefCount: no "constexpr" with libc++
Not supported by libc++.
2013-11-11 12:27:16 +01:00
Max Kellermann
faf5821816 util/LazyRandomEngine: make min()/max() static+constexpr
Required for building with libc++.
2013-11-11 12:27:15 +01:00
Max Kellermann
188673b746 output/httpd: don't use incomplete template argument with libc++ 2013-11-11 08:31:50 +01:00
Max Kellermann
287c70e361 filter/route, ...: add missing stdlib.h includes 2013-11-11 08:20:09 +01:00
Max Kellermann
f6b44af998 DespotifyUtils: add missing stdio.h include 2013-11-11 08:20:09 +01:00
Max Kellermann
84c3d9674f DecoderAPI: add missing math.h include 2013-11-11 08:18:54 +01:00
Jurgen Kramer
47d3758820 decoder/dsdiff: fix byte order bug 2013-11-10 16:49:39 +01:00
Max Kellermann
573ff3a24f DecoderThread: add missing <functional> include 2013-11-09 09:54:12 +01:00
Max Kellermann
32fcc22cb3 configure.ac: prepare for 0.18.4 2013-11-09 09:52:51 +01:00
35 changed files with 272 additions and 112 deletions

22
NEWS

@@ -1,3 +1,25 @@
ver 0.18.5 (2013/11/23)
* configuration
- fix crash when db_file is configured without music_directory
- fix crash on "stats" without db_file/music_directory
* database
- proxy: auto-reload statistics
- proxy: provide "db_update" in "stats" response
* input
- curl: work around stream resume bug (fixed in libcurl 7.32.0)
* decoder
- fluidsynth: auto-detect by default
* clip 24 bit data from libsamplerate
* fix ia64, mipsel and other little-endian architectures
* fix build failures due to missing includes
* fix build failure with static libmpdclient
ver 0.18.4 (2013/11/13)
* decoder
- dsdiff: fix byte order bug
* fix build failures due to missing includes
* libc++ compatibility
ver 0.18.3 (2013/11/08)
* fix stuck MPD after song change (0.18.2 regression)

@@ -1,6 +1,6 @@
AC_PREREQ(2.60)
AC_INIT(mpd, 0.18.3, musicpd-dev-team@lists.sourceforge.net)
AC_INIT(mpd, 0.18.5, musicpd-dev-team@lists.sourceforge.net)
VERSION_MAJOR=0
VERSION_MINOR=18
@@ -874,10 +874,12 @@ AM_CONDITIONAL(HAVE_FLAC, test x$enable_flac = xyes)
enable_flac_encoder=$enable_flac
dnl -------------------------------- FluidSynth -------------------------------
MPD_AUTO_PKG(fluidsynth, FLUIDSYNTH, [fluidsynth >= 1.1],
[fluidsynth decoder], [fluidsynth not found])
if test x$enable_fluidsynth = xyes; then
PKG_CHECK_MODULES(FLUIDSYNTH, [fluidsynth >= 1.1],
AC_DEFINE(ENABLE_FLUIDSYNTH, 1, [Define for fluidsynth support]),
enable_fluidsynth=no)
AC_DEFINE(ENABLE_FLUIDSYNTH, 1, [Define for fluidsynth support])
fi
AM_CONDITIONAL(ENABLE_FLUIDSYNTH, test x$enable_fluidsynth = xyes)

@@ -210,7 +210,6 @@ input {
# type "alsa"
# name "My ALSA Device"
## device "hw:0,0" # optional
## format "44100:16:2" # optional
## mixer_type "hardware" # optional
## mixer_device "default" # optional
## mixer_control "PCM" # optional
@@ -223,7 +222,6 @@ input {
# type "oss"
# name "My OSS Device"
## device "/dev/dsp" # optional
## format "44100:16:2" # optional
## mixer_type "hardware" # optional
## mixer_device "/dev/mixer" # optional
## mixer_control "PCM" # optional
@@ -327,12 +325,6 @@ input {
# mixer_type "none" # optional
#}
#
# This setting will change all decoded audio to be converted to the specified
# format before being passed to the audio outputs. By default, this setting is
# disabled.
#
#audio_output_format "44100:16:2"
#
# If MPD has been compiled with libsamplerate support, this setting specifies
# the sample rate converter to use. Possible values can be found in the
# mpd.conf man page or the libsamplerate documentation. By default, this is

@@ -148,12 +148,12 @@ DatabaseGlobalOpen(Error &error)
return true;
}
time_t
db_get_mtime(void)
bool
db_exists()
{
assert(db != nullptr);
assert(db_is_open);
assert(db_is_simple());
return ((SimpleDatabase *)db)->GetLastModified();
return ((SimpleDatabase *)db)->GetUpdateStamp() > 0;
}

@@ -30,6 +30,8 @@
#include "tag/TagType.h"
#include "Compiler.h"
#include <time.h>
struct config_param;
struct DatabaseSelection;
struct db_visitor;
@@ -132,6 +134,13 @@ public:
virtual bool GetStats(const DatabaseSelection &selection,
DatabaseStats &stats,
Error &error) const = 0;
/**
* Returns the time stamp of the last database update.
* Returns 0 if that is not not known/available.
*/
gcc_pure
virtual time_t GetUpdateStamp() const = 0;
};
struct DatabasePlugin {

@@ -62,25 +62,13 @@ db_get_directory(const char *name);
bool
db_save(Error &error);
/**
* May only be used if db_is_simple() returns true.
*/
gcc_pure
time_t
db_get_mtime(void);
/**
* Returns true if there is a valid database file on the disk.
*
* May only be used if db_is_simple() returns true.
*/
gcc_pure
static inline bool
db_exists(void)
{
/* mtime is set only if the database file was loaded or saved
successfully */
return db_get_mtime() > 0;
}
bool
db_exists();
#endif

@@ -35,6 +35,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void
decoder_initialized(Decoder &decoder,

@@ -38,6 +38,8 @@
#include "tag/ApeReplayGain.hxx"
#include "Log.hxx"
#include <functional>
static constexpr Domain decoder_thread_domain("decoder_thread");
/**

@@ -28,6 +28,8 @@ extern "C" {
#include <despotify.h>
}
#include <stdio.h>
const Domain despotify_domain("despotify");
static struct despotify_session *g_session;

@@ -133,7 +133,9 @@ void mapper_finish(void)
const char *
mapper_get_music_directory_utf8(void)
{
return music_dir_utf8.c_str();
return music_dir_utf8.empty()
? nullptr
: music_dir_utf8.c_str();
}
const AllocatedPath &

@@ -41,7 +41,8 @@ mapper_init(AllocatedPath &&music_dir, AllocatedPath &&playlist_dir);
void mapper_finish(void);
/**
* Return the absolute path of the music directory encoded in UTF-8.
* Return the absolute path of the music directory encoded in UTF-8 or
* nullptr if no music directory was configured.
*/
gcc_const
const char *

@@ -30,6 +30,7 @@
#include "util/Domain.hxx"
#include <string.h>
#include <stdlib.h>
#define SONG_MTIME "mtime"
#define SONG_END "song_end"

@@ -30,59 +30,75 @@
#include <glib.h>
struct stats stats;
static GTimer *uptime;
static DatabaseStats stats;
void stats_global_init(void)
{
stats.timer = g_timer_new();
uptime = g_timer_new();
}
void stats_global_finish(void)
{
g_timer_destroy(stats.timer);
g_timer_destroy(uptime);
}
void stats_update(void)
{
assert(GetDatabase() != nullptr);
Error error;
DatabaseStats stats2;
const DatabaseSelection selection("", true);
if (GetDatabase()->GetStats(selection, stats2, error)) {
stats.song_count = stats2.song_count;
stats.song_duration = stats2.total_duration;
stats.artist_count = stats2.artist_count;
stats.album_count = stats2.album_count;
stats = stats2;
} else {
LogError(error);
stats.song_count = 0;
stats.song_duration = 0;
stats.artist_count = 0;
stats.album_count = 0;
stats.Clear();
}
}
static void
db_stats_print(Client &client)
{
assert(GetDatabase() != nullptr);
if (!db_is_simple())
/* reload statistics if we're using the "proxy"
database plugin */
/* TODO: move this into the "proxy" database plugin as
an "idle" handler */
stats_update();
client_printf(client,
"artists: %u\n"
"albums: %u\n"
"songs: %u\n"
"db_playtime: %lu\n",
stats.artist_count,
stats.album_count,
stats.song_count,
stats.total_duration);
const time_t update_stamp = GetDatabase()->GetUpdateStamp();
if (update_stamp > 0)
client_printf(client,
"db_update: %lu\n",
(unsigned long)update_stamp);
}
void
stats_print(Client &client)
{
client_printf(client,
"artists: %u\n"
"albums: %u\n"
"songs: %i\n"
"uptime: %li\n"
"playtime: %li\n"
"db_playtime: %li\n",
stats.artist_count,
stats.album_count,
stats.song_count,
(long)g_timer_elapsed(stats.timer, NULL),
(long)(client.player_control.GetTotalPlayTime() + 0.5),
stats.song_duration);
"uptime: %lu\n"
"playtime: %lu\n",
(unsigned long)g_timer_elapsed(uptime, NULL),
(unsigned long)(client.player_control.GetTotalPlayTime() + 0.5));
if (db_is_simple())
client_printf(client,
"db_update: %li\n",
(long)db_get_mtime());
if (GetDatabase() != nullptr)
db_stats_print(client);
}

@@ -21,26 +21,6 @@
#define MPD_STATS_HXX
class Client;
typedef struct _GTimer GTimer;
struct stats {
GTimer *timer;
/** number of song files in the music directory */
unsigned song_count;
/** sum of all song durations in the music directory (in
seconds) */
unsigned long song_duration;
/** number of distinct artist names in the music directory */
unsigned artist_count;
/** number of distinct album names in the music directory */
unsigned album_count;
};
extern struct stats stats;
void stats_global_init(void);

@@ -190,18 +190,16 @@ iso9660_input_read(InputStream *is, void *ptr, size_t size,
Error &error)
{
Iso9660InputStream *iis = (Iso9660InputStream *)is;
int toread, readed = 0;
int readed = 0;
int no_blocks, cur_block;
size_t left_bytes = iis->statbuf->size - is->offset;
size = (size * ISO_BLOCKSIZE) / ISO_BLOCKSIZE;
if (left_bytes < size) {
toread = left_bytes;
no_blocks = CEILING(left_bytes,ISO_BLOCKSIZE);
} else {
toread = size;
no_blocks = toread / ISO_BLOCKSIZE;
no_blocks = size / ISO_BLOCKSIZE;
}
if (no_blocks > 0) {

@@ -46,6 +46,9 @@ class ProxyDatabase : public Database {
struct mpd_connection *connection;
Directory *root;
/* this is mutable because GetStats() must be "const" */
mutable time_t update_stamp;
public:
static Database *Create(const config_param &param,
Error &error);
@@ -71,6 +74,10 @@ public:
DatabaseStats &stats,
Error &error) const override;
virtual time_t GetUpdateStamp() const override {
return update_stamp;
}
private:
bool Configure(const config_param &param, Error &error);
@@ -237,6 +244,7 @@ ProxyDatabase::Open(Error &error)
return false;
root = Directory::NewRoot();
update_stamp = 0;
return true;
}
@@ -631,6 +639,8 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection,
if (stats2 == nullptr)
return CheckError(connection, error);
update_stamp = (time_t)mpd_stats_get_db_update_time(stats2);
stats.song_count = mpd_stats_get_number_of_songs(stats2);
stats.total_duration = mpd_stats_get_db_play_time(stats2);
stats.artist_count = mpd_stats_get_number_of_artists(stats2);

@@ -26,8 +26,6 @@
#include <cassert>
#include <time.h>
struct Directory;
class SimpleDatabase : public Database {
@@ -55,11 +53,6 @@ public:
bool Save(Error &error);
gcc_pure
time_t GetLastModified() const {
return mtime;
}
static Database *Create(const config_param &param,
Error &error);
@@ -85,6 +78,10 @@ public:
DatabaseStats &stats,
Error &error) const override;
virtual time_t GetUpdateStamp() const override {
return mtime;
}
protected:
bool Configure(const config_param &param, Error &error);

@@ -47,6 +47,17 @@ public:
}
};
class DffDsdUint64 {
uint32_t hi;
uint32_t lo;
public:
constexpr uint64_t Read() const {
return (uint64_t(FromBE32(hi)) << 32) |
uint64_t(FromBE32(lo));
}
};
bool
dsdlib_read(Decoder *decoder, InputStream &is,
void *data, size_t length);

@@ -43,13 +43,13 @@
struct DsdiffHeader {
DsdId id;
DsdUint64 size;
DffDsdUint64 size;
DsdId format;
};
struct DsdiffChunkHeader {
DsdId id;
DsdUint64 size;
DffDsdUint64 size;
/**
* Read the "size" attribute from the specified header, converting it
@@ -294,7 +294,6 @@ dsdiff_read_metadata_extra(Decoder *decoder, InputStream &is,
if (!dsdiff_read_chunk_header(decoder, is, chunk_header))
return false;
}
chunk_size = 0;
}
/* done processing chunk headers, process tags if any */
@@ -385,10 +384,10 @@ dsdiff_decode_chunk(Decoder &decoder, InputStream &is,
while (chunk_size > 0) {
/* see how much aligned data from the remaining chunk
fits into the local buffer */
unsigned now_frames = buffer_frames;
size_t now_size = buffer_size;
if (chunk_size < (uint64_t)now_size) {
now_frames = (unsigned)chunk_size / frame_size;
unsigned now_frames =
(unsigned)chunk_size / frame_size;
now_size = now_frames * frame_size;
}

@@ -240,10 +240,10 @@ dsf_decode_chunk(Decoder &decoder, InputStream &is,
while (chunk_size > 0) {
/* see how much aligned data from the remaining chunk
fits into the local buffer */
unsigned now_frames = buffer_frames;
size_t now_size = buffer_size;
if (chunk_size < (uint64_t)now_size) {
now_frames = (unsigned)chunk_size / frame_size;
unsigned now_frames =
(unsigned)chunk_size / frame_size;
now_size = now_frames * frame_size;
}

@@ -22,6 +22,8 @@
#include "OggSyncState.hxx"
#include "util/Error.hxx"
#include <stdio.h>
bool
OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet)
{

@@ -34,6 +34,7 @@
#include <glib.h>
#include <assert.h>
#include <stdlib.h>
struct opus_encoder {
/** the base class */

@@ -56,6 +56,7 @@
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
class RouteFilter final : public Filter {
/**

@@ -273,12 +273,27 @@ public:
SocketAction(CURL_SOCKET_TIMEOUT, 0);
}
/**
* This is a kludge to allow pausing/resuming a stream with
* libcurl < 7.32.0. Read the curl_easy_pause manpage for
* more information.
*/
void ResumeSockets() {
int running_handles;
curl_multi_socket_all(multi, &running_handles);
}
private:
static int TimerFunction(CURLM *multi, long timeout_ms, void *userp);
virtual void OnTimeout() override;
};
/**
* libcurl version number encoded in a 24 bit integer.
*/
static unsigned curl_version_num;
/** libcurl should accept "ICY 200 OK" */
static struct curl_slist *http_200_aliases;
@@ -330,6 +345,13 @@ input_curl_resume(struct input_curl *c)
if (c->paused) {
c->paused = false;
curl_easy_pause(c->easy, CURLPAUSE_CONT);
if (curl_version_num < 0x072000)
/* libcurl older than 7.32.0 does not update
its sockets after curl_easy_pause(); force
libcurl to do it now */
curl_multi->ResumeSockets();
curl_multi->InvalidateSockets();
}
}
@@ -586,6 +608,16 @@ input_curl_init(const config_param &param, Error &error)
return false;
}
const auto version_info = curl_version_info(CURLVERSION_FIRST);
if (version_info != nullptr) {
FormatDebug(curl_domain, "version %s", version_info->version);
if (version_info->features & CURL_VERSION_SSL)
FormatDebug(curl_domain, "with %s",
version_info->ssl_version);
curl_version_num = version_info->version_num;
}
http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK");
proxy = param.GetBlockValue("proxy");

@@ -30,6 +30,11 @@
#include "thread/Mutex.hxx"
#include "event/ServerSocket.hxx"
#ifdef _LIBCPP_VERSION
/* can't use incomplete template arguments with libc++ */
#include "HttpdClient.hxx"
#endif
#include <forward_list>
struct config_param;

@@ -148,3 +148,26 @@ PcmResampler::Resample32(unsigned channels, unsigned src_rate,
src_rate, src_buffer, src_size,
dest_rate, dest_size_r);
}
const int32_t *
PcmResampler::Resample24(unsigned channels, unsigned src_rate,
const int32_t *src_buffer, size_t src_size,
unsigned dest_rate, size_t *dest_size_r,
Error &error_r)
{
#ifdef HAVE_LIBSAMPLERATE
if (pcm_resample_lsr_enabled())
return pcm_resample_lsr_24(this, channels,
src_rate, src_buffer, src_size,
dest_rate, dest_size_r,
error_r);
#else
(void)error_r;
#endif
/* reuse the 32 bit code - the resampler code doesn't care if
the upper 8 bits are actually used */
return pcm_resample_fallback_32(this, channels,
src_rate, src_buffer, src_size,
dest_rate, dest_size_r);
}

@@ -124,13 +124,7 @@ struct PcmResampler {
const int32_t *Resample24(unsigned channels, unsigned src_rate,
const int32_t *src_buffer, size_t src_size,
unsigned dest_rate, size_t *dest_size_r,
Error &error_r)
{
/* reuse the 32 bit code - the resampler code doesn't care if
the upper 8 bits are actually used */
return Resample32(channels, src_rate, src_buffer, src_size,
dest_rate, dest_size_r, error_r);
}
Error &error_r);
};
bool

@@ -69,6 +69,15 @@ pcm_resample_lsr_32(PcmResampler *state,
unsigned dest_rate, size_t *dest_size_r,
Error &error);
const int32_t *
pcm_resample_lsr_24(PcmResampler *state,
unsigned channels,
unsigned src_rate,
const int32_t *src_buffer,
size_t src_size,
unsigned dest_rate, size_t *dest_size_r,
Error &error);
#endif
const int16_t *

@@ -19,6 +19,7 @@
#include "config.h"
#include "PcmResampleInternal.hxx"
#include "PcmUtils.hxx"
#include "util/ASCII.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
@@ -283,3 +284,27 @@ pcm_resample_lsr_32(PcmResampler *state,
return dest_buffer;
}
const int32_t *
pcm_resample_lsr_24(PcmResampler *state,
unsigned channels,
unsigned src_rate,
const int32_t *src_buffer, size_t src_size,
unsigned dest_rate, size_t *dest_size_r,
Error &error)
{
const auto result = pcm_resample_lsr_32(state, channels,
src_rate, src_buffer, src_size,
dest_rate, dest_size_r,
error);
if (result != nullptr)
/* src_float_to_int_array() clamps for 32 bit
integers; now make sure everything's fine for 24
bit */
/* TODO: eliminate the 32 bit clamp to reduce overhead */
PcmClampN<int32_t, int32_t, 24>(const_cast<int32_t *>(result),
result,
*dest_size_r / sizeof(*result));
return result;
}

@@ -63,4 +63,16 @@ PcmClamp(U x)
return T(x);
}
/**
* Check if the values in this buffer are within the range of the
* provided bit size, and clamps them whenever necessary.
*/
template<typename T, typename U, unsigned bits>
static inline void
PcmClampN(T *dest, const U *src, unsigned n)
{
while (n-- > 0)
*dest++ = PcmClamp<T, U, bits>(*src++);
}
#endif

@@ -33,11 +33,23 @@
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
#define IS_LITTLE_ENDIAN true
#define IS_BIG_ENDIAN false
/* well-known little-endian */
# define IS_LITTLE_ENDIAN true
# define IS_BIG_ENDIAN false
#elif defined(__MIPSEB__)
/* well-known big-endian */
# define IS_LITTLE_ENDIAN false
# define IS_BIG_ENDIAN true
#else
#define IS_LITTLE_ENDIAN false
#define IS_BIG_ENDIAN true
/* generic compile-time check */
# include <endian.h>
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define IS_LITTLE_ENDIAN true
# define IS_BIG_ENDIAN false
# else
# define IS_LITTLE_ENDIAN false
# define IS_BIG_ENDIAN true
# endif
#endif
static inline constexpr bool

@@ -104,6 +104,11 @@ socketpair_cloexec_nonblock(int domain, int type, int protocol, int sv[2]);
#endif
#ifdef HAVE_LIBMPDCLIENT
/* Avoid symbol conflict with statically linked libmpdclient */
#define socket_cloexec_nonblock socket_cloexec_nonblock_noconflict
#endif
/**
* Wrapper for socket(), which sets the CLOEXEC and the NONBLOCK flag
* (atomically if supported by the OS).

@@ -49,12 +49,12 @@ public:
*/
void AutoCreate();
result_type min() const {
return engine->min();
static constexpr result_type min() {
return std::mt19937::min();
}
result_type max() const {
return engine->max();
static constexpr result_type max() {
return std::mt19937::max();
}
result_type operator()() {

@@ -42,7 +42,12 @@ class RefCount {
std::atomic_uint n;
public:
constexpr RefCount():n(1) {}
#ifndef _LIBCPP_VERSION
/* the "constexpr" is missing in libc++'s "atomic"
implementation */
constexpr
#endif
RefCount():n(1) {}
void Increment() {
++n;

@@ -36,6 +36,7 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
static void