Changeset 967

Show
Ignore:
Timestamp:
03/22/08 14:48:09 (13 years ago)
Author:
ppalmers
Message:

- first attempt at not causing total havoc when devices are removed from the bus.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/libffado/ffado.h

    r864 r967  
    222222 */ 
    223223typedef enum { 
     224    ffado_wait_shutdown        = -3, 
    224225    ffado_wait_error           = -2, 
    225226    ffado_wait_xrun            = -1, 
  • trunk/libffado/SConstruct

    r948 r967  
    2424# 
    2525 
    26 FFADO_API_VERSION="7
    27 FFADO_VERSION="1.999.16
     26FFADO_API_VERSION="8
     27FFADO_VERSION="1.999.17
    2828 
    2929import os 
  • trunk/libffado/src/devicemanager.cpp

    r964 r967  
    225225    { 
    226226        (*it)->handleBusReset(); 
     227    } 
     228 
     229    // notify the streamprocessormanager of the busreset 
     230    if(m_processorManager) { 
     231        m_processorManager->handleBusReset(); 
     232    } else { 
     233        debugWarning("No valid SPM\n"); 
    227234    } 
    228235 
     
    732739        return eWR_OK; 
    733740    } else { 
    734         debugWarning("XRUN detected\n"); 
    735         // do xrun recovery 
    736         if(m_processorManager->handleXrun()) { 
    737             return eWR_Xrun; 
     741        if(m_processorManager->shutdownNeeded()) { 
     742            debugWarning("Shutdown requested\n"); 
     743            return eWR_Shutdown; 
    738744        } else { 
    739             debugError("Could not handle XRUN\n"); 
    740             return eWR_Error; 
     745            debugWarning("XRUN detected\n"); 
     746            // do xrun recovery 
     747            if(m_processorManager->handleXrun()) { 
     748                return eWR_Xrun; 
     749            } else { 
     750                debugError("Could not handle XRUN\n"); 
     751                return eWR_Error; 
     752            } 
    741753        } 
    742754    } 
  • trunk/libffado/src/devicemanager.h

    r960 r967  
    7272        eWR_Xrun, 
    7373        eWR_Error, 
     74        eWR_Shutdown, 
    7475    }; 
    7576 
  • trunk/libffado/src/ffado.cpp

    r864 r967  
    251251        xruns++; 
    252252        return ffado_wait_xrun; 
     253    } else if (result == DeviceManager::eWR_Shutdown) { 
     254        debugWarning("Streaming system requests shutdown.\n"); 
     255        return ffado_wait_shutdown; 
    253256    } else { 
    254         debugError("Unhandled XRUN (BUG)\n"); 
     257        debugError("Error condition while waiting (Unhandled XRUN)\n"); 
    255258        xruns++; 
    256259        return ffado_wait_error; 
  • trunk/libffado/src/ffadodevice.cpp

    r958 r967  
    142142FFADODevice::setId( unsigned int id) 
    143143{ 
     144    m_DeviceMutex.Lock(); 
    144145    bool retval; 
    145146    // FIXME: decent ID system nescessary 
     
    149150 
    150151    retval=setOption("id",idstr.str()); 
     152    m_DeviceMutex.Unlock(); 
    151153    return retval; 
    152154} 
     
    156158{ 
    157159    debugOutput( DEBUG_LEVEL_VERBOSE, "Handle bus reset...\n"); 
    158      
     160 
    159161    // update the config rom node id 
    160162    sleep(1); 
     163 
     164    m_DeviceMutex.Lock(); 
    161165    getConfigRom().setVerboseLevel(getDebugLevel()); 
    162166    getConfigRom().updatedNodeId(); 
    163  
     167    m_DeviceMutex.Unlock(); 
    164168} 
    165169 
     
    169173    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
    170174    setDebugLevel(l); 
     175    m_DeviceMutex.setVerboseLevel(l); 
    171176    getConfigRom().setVerboseLevel(l); 
    172177} 
  • trunk/libffado/src/ffadodevice.h

    r958 r967  
    2727 
    2828#include "libutil/OptionContainer.h" 
     29#include "libutil/PosixMutex.h" 
     30 
    2931#include "libcontrol/BasicElements.h" 
    3032 
     
    438440protected: 
    439441    DECLARE_DEBUG_MODULE; 
     442    Util::PosixMutex m_DeviceMutex; 
    440443}; 
    441444 
  • trunk/libffado/src/genericavc/avc_avdevice.cpp

    r864 r967  
    9898AvDevice::discover() 
    9999{ 
     100    m_DeviceMutex.Lock(); 
    100101    // check if we already have a valid VendorModel entry 
    101102    // e.g. because a subclass called this function 
     
    110111 
    111112        if (!GenericAVC::VendorModel::isValid(m_model)) { 
     113            m_DeviceMutex.Unlock(); 
    112114            return false; 
    113115        } 
     
    118120    if ( !Unit::discover() ) { 
    119121        debugError( "Could not discover unit\n" ); 
     122        m_DeviceMutex.Unlock(); 
    120123        return false; 
    121124    } 
     
    123126    if((getAudioSubunit( 0 ) == NULL)) { 
    124127        debugError( "Unit doesn't have an Audio subunit.\n"); 
     128        m_DeviceMutex.Unlock(); 
    125129        return false; 
    126130    } 
    127131    if((getMusicSubunit( 0 ) == NULL)) { 
    128132        debugError( "Unit doesn't have a Music subunit.\n"); 
    129         return false; 
    130     } 
     133        m_DeviceMutex.Unlock(); 
     134        return false; 
     135    } 
     136    m_DeviceMutex.Unlock(); 
    131137 
    132138    return true; 
     
    136142AvDevice::setVerboseLevel(int l) 
    137143{ 
     144    m_DeviceMutex.Lock(); 
    138145    setDebugLevel(l); 
    139146    m_pPlugManager->setVerboseLevel(l); 
     
    141148    AVC::Unit::setVerboseLevel(l); 
    142149    debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l ); 
     150    m_DeviceMutex.Unlock(); 
    143151} 
    144152 
     
    168176AvDevice::setSamplingFrequency( int s ) 
    169177{ 
     178    m_DeviceMutex.Lock(); 
    170179    bool snoopMode=false; 
    171180    if(!getOption("snoopMode", snoopMode)) { 
     
    178187            debugError("In snoop mode it is impossible to set the sample rate.\n"); 
    179188            debugError("Please start the client with the correct setting.\n"); 
    180             return false; 
    181         } 
     189            m_DeviceMutex.Unlock(); 
     190            return false; 
     191        } 
     192        m_DeviceMutex.Unlock(); 
    182193        return true; 
    183194    } else { 
     
    185196        if ( !plug ) { 
    186197            debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); 
     198            m_DeviceMutex.Unlock(); 
    187199            return false; 
    188200        } 
     
    191203        { 
    192204            debugError( "setSampleRate: Setting sample rate failed\n" ); 
     205            m_DeviceMutex.Unlock(); 
    193206            return false; 
    194207        } 
     
    197210        if ( !plug ) { 
    198211            debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); 
     212            m_DeviceMutex.Unlock(); 
    199213            return false; 
    200214        } 
     
    203217        { 
    204218            debugError( "setSampleRate: Setting sample rate failed\n" ); 
     219            m_DeviceMutex.Unlock(); 
    205220            return false; 
    206221        } 
     
    209224                     "setSampleRate: Set sample rate to %d\n", 
    210225                     s ); 
     226        m_DeviceMutex.Unlock(); 
    211227        return true; 
    212228    } 
    213229    // not executable 
     230    m_DeviceMutex.Unlock(); 
    214231    return false; 
    215232 
     
    219236AvDevice::getSupportedClockSources() { 
    220237    FFADODevice::ClockSourceVector r; 
     238 
     239    m_DeviceMutex.Lock(); 
    221240 
    222241    PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType( 
     
    256275    } 
    257276 
     277    m_DeviceMutex.Unlock(); 
    258278    return r; 
    259279} 
     
    267287    } 
    268288 
     289    m_DeviceMutex.Lock(); 
    269290    for ( SyncInfoVector::const_iterator it 
    270291              = getSyncInfos().begin(); 
     
    275296 
    276297        if (si.m_source==src) { 
     298            m_DeviceMutex.Unlock(); 
    277299            return setActiveSync(si); 
    278300        } 
    279301    } 
     302    m_DeviceMutex.Unlock(); 
    280303 
    281304    return false; 
     
    368391AvDevice::lock() { 
    369392    bool snoopMode=false; 
     393    m_DeviceMutex.Lock(); 
    370394    if(!getOption("snoopMode", snoopMode)) { 
    371395        debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); 
     
    377401//         return Unit::reserve(4); 
    378402    } 
     403    m_DeviceMutex.Unlock(); 
    379404 
    380405    return true; 
     
    384409AvDevice::unlock() { 
    385410    bool snoopMode=false; 
     411    m_DeviceMutex.Lock(); 
    386412    if(!getOption("snoopMode", snoopMode)) { 
    387413        debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); 
     
    393419//         return Unit::reserve(0); 
    394420    } 
     421    m_DeviceMutex.Unlock(); 
    395422    return true; 
    396423} 
     
    408435AvDevice::prepare() { 
    409436    bool snoopMode=false; 
     437    m_DeviceMutex.Lock(); 
    410438    if(!getOption("snoopMode", snoopMode)) { 
    411439        debugWarning("Could not retrieve snoopMode parameter, defauling to false\n"); 
     
    418446    if ( !inputPlug ) { 
    419447        debugError( "setSampleRate: Could not retrieve iso input plug 0\n" ); 
     448        m_DeviceMutex.Unlock(); 
    420449        return false; 
    421450    } 
     
    423452    if ( !outputPlug ) { 
    424453        debugError( "setSampleRate: Could not retrieve iso output plug 0\n" ); 
     454        m_DeviceMutex.Unlock(); 
    425455        return false; 
    426456    } 
     
    432462    if ( outputPlug->getNrOfChannels() == 0 ) { 
    433463        debugError("Receive plug has no channels\n"); 
     464        m_DeviceMutex.Unlock(); 
    434465        return false; 
    435466    } 
     
    440471        debugFatal("Could not initialize receive processor!\n"); 
    441472        delete p; 
     473        m_DeviceMutex.Unlock(); 
    442474        return false; 
    443475    } 
     
    447479        debugFatal("Could not add plug to processor!\n"); 
    448480        delete p; 
     481        m_DeviceMutex.Unlock(); 
    449482        return false; 
    450483    } 
     
    468501            (snoopMode?" in snoop mode":"")); 
    469502        delete p; 
     503        m_DeviceMutex.Unlock(); 
    470504        return false; 
    471505    } 
     
    475509            Streaming::Port::E_Capture)) { 
    476510            debugFatal("Could not add plug to processor!\n"); 
     511            m_DeviceMutex.Unlock(); 
    477512            return false; 
    478513        } 
     
    481516            Streaming::Port::E_Playback)) { 
    482517            debugFatal("Could not add plug to processor!\n"); 
     518            m_DeviceMutex.Unlock(); 
    483519            return false; 
    484520        } 
     
    491527    m_transmitProcessors.push_back(p); 
    492528 
     529    m_DeviceMutex.Unlock(); 
    493530    return true; 
    494531} 
     
    592629int 
    593630AvDevice::getStreamCount() { 
    594     return m_receiveProcessors.size() + m_transmitProcessors.size(); 
     631    int retval; 
     632    m_DeviceMutex.Lock(); 
     633    retval = m_receiveProcessors.size() + m_transmitProcessors.size(); 
     634    m_DeviceMutex.Unlock(); 
     635    return retval; 
    595636    //return 1; 
    596637} 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r930 r967  
    353353    raw1394_read(m_handle, raw1394_get_local_id(m_handle), 
    354354                 CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
     355 
     356    // notify the client of the fact that we have died 
     357    m_Client->handlerDied(); 
     358 
     359    if(!disable()) { 
     360        debugError("(%p) Could not disable IsoHandler\n", this); 
     361    } 
     362 
     363    // request the manager to update it's shadow map 
     364    m_manager.requestShadowMapUpdate(); 
    355365    return 0; 
    356366} 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r940 r967  
    292292} 
    293293 
     294void 
     295IsoHandlerManager::requestShadowMapUpdate() 
     296{ 
     297    if(m_IsoTask) m_IsoTask->requestShadowMapUpdate(); 
     298} 
     299 
    294300bool 
    295301IsoHandlerManager::setThreadParameters(bool rt, int priority) { 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.h

    r938 r967  
    107107    friend class Streaming::StreamProcessorManager; 
    108108    friend class IsoTask; 
     109    friend class IsoHandler; 
    109110 
    110111    public: 
     
    151152        Ieee1394Service& get1394Service() {return m_service;}; 
    152153 
     154    protected: 
     155        void requestShadowMapUpdate(); 
     156 
    153157    // the state machine 
    154158    private: 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r938 r967  
    9898    if (m_data_buffer) delete m_data_buffer; 
    9999    if (m_scratch_buffer) delete[] m_scratch_buffer; 
     100} 
     101 
     102void 
     103StreamProcessor::handleBusReset() 
     104{ 
     105    debugOutput(DEBUG_LEVEL_VERBOSE, "(%p) handling busreset\n", this); 
     106    // for now, we try and make sure everything is cleanly shutdown 
     107    if(!stopRunning(-1)) { 
     108        debugError("Failed to stop SP\n"); 
     109    } 
     110    SIGNAL_ACTIVITY; 
     111} 
     112 
     113void StreamProcessor::handlerDied() 
     114{ 
     115    debugWarning("Handler died for %p\n", this); 
     116    m_state = ePS_Stopped; 
     117    m_in_xrun = true; 
    100118} 
    101119 
     
    12081226 
    12091227bool StreamProcessor::startDryRunning(int64_t t) { 
     1228    if(getState() == ePS_DryRunning) { 
     1229        // already in the correct state 
     1230        return true; 
     1231    } 
    12101232    if(!scheduleStartDryRunning(t)) { 
    12111233        debugError("Could not schedule transition\n"); 
     
    12201242 
    12211243bool StreamProcessor::startRunning(int64_t t) { 
     1244    if(getState() == ePS_Running) { 
     1245        // already in the correct state 
     1246        return true; 
     1247    } 
    12221248    if(!scheduleStartRunning(t)) { 
    12231249        debugError("Could not schedule transition\n"); 
     
    12321258 
    12331259bool StreamProcessor::stopDryRunning(int64_t t) { 
     1260    if(getState() == ePS_Stopped) { 
     1261        // already in the correct state 
     1262        return true; 
     1263    } 
    12341264    if(!scheduleStopDryRunning(t)) { 
    12351265        debugError("Could not schedule transition\n"); 
     
    12441274 
    12451275bool StreamProcessor::stopRunning(int64_t t) { 
     1276    if(getState() == ePS_DryRunning) { 
     1277        // already in the correct state 
     1278        return true; 
     1279    } 
    12461280    if(!scheduleStopRunning(t)) { 
    12471281        debugError("Could not schedule transition\n"); 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r930 r967  
    7373        ePS_Invalid, 
    7474        ePS_Created, 
    75         // ePS_WaitingToStop, FIXME: this will be needed for the MOTU's 
    7675        ePS_Stopped, 
    7776        ePS_WaitingForStream, 
     
    131130    bool init(); 
    132131    bool prepare(); 
     132 
     133    void handleBusReset(); 
    133134 
    134135public: // constructor/destructor 
     
    294295    // move to private? 
    295296    bool xrunOccurred() { return m_in_xrun; }; 
     297    void handlerDied(); 
    296298 
    297299// the ISO interface (can we get rid of this?) 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r918 r967  
    4747    , m_nominal_framerate ( 0 ) 
    4848    , m_xruns(0) 
     49    , m_shutdown_needed(false) 
    4950    , m_nbperiods(0) 
    5051{ 
     
    6162    , m_nominal_framerate ( framerate ) 
    6263    , m_xruns(0) 
     64    , m_shutdown_needed(false) 
    6365    , m_nbperiods(0) 
    6466{ 
     
    6769 
    6870StreamProcessorManager::~StreamProcessorManager() { 
     71} 
     72 
     73void 
     74StreamProcessorManager::handleBusReset() 
     75{ 
     76    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) Handle bus reset...\n", this); 
     77 
     78    // FIXME: we request shutdown for now. 
     79    m_shutdown_needed=true; 
     80 
     81    // note that all receive streams are gone once a device is unplugged 
     82 
     83    // synchronize with the wait lock 
     84    m_WaitLock.Lock(); 
     85 
     86    debugOutput( DEBUG_LEVEL_VERBOSE, "(%p) got wait lock...\n", this); 
     87    // cause all SP's to bail out 
     88    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     89          it != m_ReceiveProcessors.end(); 
     90          ++it ) 
     91    { 
     92        (*it)->handleBusReset(); 
     93    } 
     94    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     95          it != m_TransmitProcessors.end(); 
     96          ++it ) 
     97    { 
     98        (*it)->handleBusReset(); 
     99    } 
     100 
     101    m_WaitLock.Unlock(); 
    69102} 
    70103 
     
    151184 
    152185    debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing...\n"); 
    153  
    154186    m_is_slave=false; 
    155187    if(!getOption("slaveMode", m_is_slave)) { 
    156188        debugWarning("Could not retrieve slaveMode parameter, defaulting to false\n"); 
    157189    } 
     190 
     191    m_shutdown_needed=false; 
    158192 
    159193    // if no sync source is set, select one here 
     
    692726    bool start_result = false; 
    693727    for (int ntries=0; ntries < STREAMPROCESSORMANAGER_SYNCSTART_TRIES; ntries++) { 
     728        if(m_shutdown_needed) { 
     729            debugOutput(DEBUG_LEVEL_VERBOSE, "Shutdown requested...\n"); 
     730            return true; 
     731        } 
    694732        // put all SP's into dry-running state 
    695733        if (!startDryRunning()) { 
     
    722760 * ready to be transferred. 
    723761 * 
    724  * @return true if the period is ready, false if an xrun occurred 
     762 * @return true if the period is ready, false if not 
    725763 */ 
    726764bool StreamProcessorManager::waitForPeriod() { 
    727765    if(m_SyncSource == NULL) return false; 
     766    if(m_shutdown_needed) return false; 
    728767    bool xrun_occurred = false; 
    729768    bool period_not_ready = true; 
     769 
     770    // grab the wait lock 
     771    m_WaitLock.Lock(); 
    730772 
    731773    while(period_not_ready) { 
     
    778820        if(xrun_occurred) break; 
    779821        // FIXME: make sure we also exit this loop when something else happens (e.g. signal, iso error) 
     822 
     823        // if we have to shutdown due to some async event (busreset), do so 
     824        if(m_shutdown_needed) break; 
    780825    } 
    781826 
     
    861906 
    862907    m_nbperiods++; 
     908 
     909    m_WaitLock.Unlock(); 
    863910    // now we can signal the client that we are (should be) ready 
    864911    return !xrun_occurred; 
     
    10331080void StreamProcessorManager::setVerboseLevel(int l) { 
    10341081    setDebugLevel(l); 
     1082    m_WaitLock.setVerboseLevel(l); 
    10351083 
    10361084    debugOutput( DEBUG_LEVEL_VERBOSE, " Receive processors...\n"); 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.h

    r864 r967  
    3030#include "debugmodule/debugmodule.h" 
    3131#include "libutil/Thread.h" 
     32#include "libutil/PosixMutex.h" 
    3233#include "libutil/OptionContainer.h" 
    3334 
     
    5859    StreamProcessorManager(unsigned int period, unsigned int rate, unsigned int nb_buffers); 
    5960    virtual ~StreamProcessorManager(); 
     61 
     62    void handleBusReset(); 
    6063 
    6164    bool prepare(); ///< to be called after the processors are registered 
     
    102105    int getDelayedUsecs() {return m_delayed_usecs;}; 
    103106    bool xrunOccurred(); 
     107    bool shutdownNeeded() {return m_shutdown_needed;}; 
    104108    int getXrunCount() {return m_xruns;}; 
    105109 
     
    151155    unsigned int m_nominal_framerate; 
    152156    unsigned int m_xruns; 
     157    bool m_shutdown_needed; 
    153158 
    154159    unsigned int m_nbperiods; 
     160 
     161    Util::PosixMutex m_WaitLock; 
    155162 
    156163    DECLARE_DEBUG_MODULE; 
  • trunk/libffado/src/SConscript

    r959 r967  
    7575        libutil/PacketBuffer.cpp \ 
    7676        libutil/OptionContainer.cpp \ 
     77        libutil/PosixMutex.cpp \ 
    7778        libutil/PosixThread.cpp \ 
    7879        libutil/ringbuffer.c \