1 /* 2 * Copyright 2003-2021 The Music Player Daemon Project 3 * http://www.musicpd.org 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef MPD_PIPE_H 21 #define MPD_PIPE_H 22 23 #include "MusicChunkPtr.hxx" 24 #include "thread/Mutex.hxx" 25 26 #ifndef NDEBUG 27 #include "pcm/AudioFormat.hxx" 28 #endif 29 30 /** 31 * A queue of #MusicChunk objects. One party appends chunks at the 32 * tail, and the other consumes them from the head. 33 */ 34 class MusicPipe { 35 /** the first chunk */ 36 MusicChunkPtr head; 37 38 /** a pointer to the tail of the chunk */ 39 MusicChunkPtr *tail_r = &head; 40 41 /** the current number of chunks */ 42 unsigned size = 0; 43 44 /** a mutex which protects #head and #tail_r */ 45 mutable Mutex mutex; 46 47 #ifndef NDEBUG 48 AudioFormat audio_format = AudioFormat::Undefined(); 49 #endif 50 51 public: ~MusicPipe()52 ~MusicPipe() noexcept { 53 Clear(); 54 } 55 56 #ifndef NDEBUG 57 /** 58 * Checks if the audio format if the chunk is equal to the specified 59 * audio_format. 60 */ 61 [[gnu::pure]] CheckFormat(AudioFormat other) const62 bool CheckFormat(AudioFormat other) const noexcept { 63 return !audio_format.IsDefined() || 64 audio_format == other; 65 } 66 67 /** 68 * Checks if the specified chunk is enqueued in the music pipe. 69 */ 70 [[gnu::pure]] 71 bool Contains(const MusicChunk *chunk) const noexcept; 72 #endif 73 74 /** 75 * Returns the first #MusicChunk from the pipe. Returns 76 * nullptr if the pipe is empty. 77 */ 78 [[gnu::pure]] Peek() const79 const MusicChunk *Peek() const noexcept { 80 const std::scoped_lock<Mutex> protect(mutex); 81 return head.get(); 82 } 83 84 /** 85 * Removes the first chunk from the head, and returns it. 86 */ 87 MusicChunkPtr Shift() noexcept; 88 89 /** 90 * Clears the whole pipe and returns the chunks to the buffer. 91 */ 92 void Clear() noexcept; 93 94 /** 95 * Pushes a chunk to the tail of the pipe. 96 */ 97 void Push(MusicChunkPtr chunk) noexcept; 98 99 /** 100 * Returns the number of chunks currently in this pipe. 101 */ 102 [[gnu::pure]] GetSize() const103 unsigned GetSize() const noexcept { 104 const std::scoped_lock<Mutex> protect(mutex); 105 return size; 106 } 107 108 [[gnu::pure]] IsEmpty() const109 bool IsEmpty() const noexcept { 110 return GetSize() == 0; 111 } 112 }; 113 114 #endif 115