MusicPipe.hxx 2.65 KB
Newer Older
1
/*
2
 * Copyright 2003-2018 The Music Player Daemon Project
3
 * http://www.musicpd.org
4 5 6 7 8 9 10 11 12 13
 *
 * 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.
14 15 16 17
 *
 * 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.
18 19
 */

20 21
#ifndef MPD_PIPE_H
#define MPD_PIPE_H
22

23
#include "MusicChunkPtr.hxx"
24
#include "thread/Mutex.hxx"
25
#include "util/Compiler.h"
26

Andreas Wiese's avatar
Andreas Wiese committed
27
#ifndef NDEBUG
28
#include "AudioFormat.hxx"
29 30
#endif

31 32
#include <assert.h>

33
/**
34
 * A queue of #MusicChunk objects.  One party appends chunks at the
35
 * tail, and the other consumes them from the head.
Max Kellermann's avatar
Max Kellermann committed
36
 */
37 38
class MusicPipe {
	/** the first chunk */
39
	MusicChunkPtr head;
40

41
	/** a pointer to the tail of the chunk */
42
	MusicChunkPtr *tail_r = &head;
43

44
	/** the current number of chunks */
45
	unsigned size = 0;
46

47 48
	/** a mutex which protects #head and #tail_r */
	mutable Mutex mutex;
49

50
#ifndef NDEBUG
51
	AudioFormat audio_format = AudioFormat::Undefined();
52 53
#endif

54
public:
55 56
	~MusicPipe() noexcept {
		Clear();
57
	}
58

59 60 61 62 63 64
#ifndef NDEBUG
	/**
	 * Checks if the audio format if the chunk is equal to the specified
	 * audio_format.
	 */
	gcc_pure
65
	bool CheckFormat(AudioFormat other) const noexcept {
66 67 68 69 70 71 72 73
		return !audio_format.IsDefined() ||
			audio_format == other;
	}

	/**
	 * Checks if the specified chunk is enqueued in the music pipe.
	 */
	gcc_pure
74
	bool Contains(const MusicChunk *chunk) const noexcept;
75
#endif
76

77
	/**
78
	 * Returns the first #MusicChunk from the pipe.  Returns
79 80 81
	 * nullptr if the pipe is empty.
	 */
	gcc_pure
82
	const MusicChunk *Peek() const noexcept {
83
		const std::lock_guard<Mutex> protect(mutex);
84
		return head.get();
85 86 87 88 89
	}

	/**
	 * Removes the first chunk from the head, and returns it.
	 */
90
	MusicChunkPtr Shift() noexcept;
91 92 93 94

	/**
	 * Clears the whole pipe and returns the chunks to the buffer.
	 */
95
	void Clear() noexcept;
96 97 98 99

	/**
	 * Pushes a chunk to the tail of the pipe.
	 */
100
	void Push(MusicChunkPtr chunk) noexcept;
101 102 103 104 105

	/**
	 * Returns the number of chunks currently in this pipe.
	 */
	gcc_pure
106
	unsigned GetSize() const noexcept {
107
		const std::lock_guard<Mutex> protect(mutex);
108 109 110 111
		return size;
	}

	gcc_pure
112
	bool IsEmpty() const noexcept {
113 114 115
		return GetSize() == 0;
	}
};
116

117
#endif