File indexing completed on 2024-05-05 04:44:41

0001 /*  This file is part of the KDE project
0002     Copyright (C) 2008 Matthias Kretz <kretz@kde.org>
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Lesser General Public
0006     License as published by the Free Software Foundation; either
0007     version 2.1 of the License, or (at your option) version 3, or any
0008     later version accepted by the membership of KDE e.V. (or its
0009     successor approved by the membership of KDE e.V.), Nokia Corporation 
0010     (or its successors, if any) and the KDE Free Qt Foundation, which shall
0011     act as a proxy defined in Section 6 of version 3 of the license.
0012 
0013     This library is distributed in the hope that it will be useful,
0014     but WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     Lesser General Public License for more details.
0017 
0018     You should have received a copy of the GNU Lesser General Public 
0019     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020 
0021 */
0022 
0023 #include "streameventqueue_p.h"
0024 #include "phononnamespace_p.h"
0025 #include <QtDebug>
0026 
0027 namespace Phonon
0028 {
0029 
0030 //////////////////////////////////////////
0031 // any thread
0032 
0033 StreamEventQueue::StreamEventQueue()
0034     : m_dropWriteCommands(0),
0035     m_connecting(0)
0036 {
0037 }
0038 
0039 StreamEventQueue::~StreamEventQueue()
0040 {
0041 }
0042 
0043 void StreamEventQueue::setBackendCommandHandler(LockFreeQueueBase::DataReadyHandler *h)
0044 {
0045     m_forBackend.setDataReadyHandler(h);
0046 }
0047 
0048 void StreamEventQueue::setFrontendCommandHandler(LockFreeQueueBase::DataReadyHandler *h)
0049 {
0050     m_forFrontend.setDataReadyHandler(h);
0051 }
0052 
0053 
0054 //////////////////////////////////////////
0055 // frontend thread
0056 
0057 void StreamEventQueue::sendToBackend(CommandType command, const QVariant &data)
0058 {
0059     m_forBackend.enqueue(Command(command, data));
0060 }
0061 
0062 bool StreamEventQueue::nextCommandForFrontend(Command *command)
0063 {
0064     Q_ASSERT(command);
0065     return m_forFrontend.dequeue(command);
0066 }
0067 
0068 
0069 //////////////////////////////////////////
0070 // backend thread
0071 
0072 void StreamEventQueue::sendToFrontend(CommandType command, const QVariant &data)
0073 {
0074     switch (command) {
0075     case Seek:
0076     case Reset:
0077         ++m_dropWriteCommands;
0078         break;
0079     case Connect:
0080         ++m_connecting;
0081         m_dropWriteCommands = 0;
0082         break;
0083     default:
0084         break;
0085     }
0086     m_forFrontend.enqueue(Command(command, data));
0087 }
0088 
0089 bool StreamEventQueue::nextCommandForBackend(Command *command)
0090 {
0091     Q_ASSERT(command);
0092     bool valid = m_forBackend.dequeue(command);
0093     while (valid) {
0094         if (m_connecting) {
0095             if (command->command == ConnectDone) {
0096                 --m_connecting;
0097             }
0098             // drop all other commands until m_connecting == 0
0099         } else if (m_dropWriteCommands) {
0100             switch (command->command) {
0101             case Write:
0102             case EndOfData:
0103                 // drop until m_dropWriteCommands == 0
0104                 break;
0105             case SeekDone:
0106             case ResetDone:
0107                 --m_dropWriteCommands;
0108                 break;
0109             case ConnectDone:
0110                 pFatal("received a ConnectDone, but there was no Connect request");
0111                 break;
0112             default:
0113                 return valid;
0114             }
0115         } else {
0116             return valid;
0117         }
0118         valid = m_forBackend.dequeue(command);
0119     }
0120     return valid;
0121 }
0122 
0123 } // namespace Phonon