Changeset 309

Show
Ignore:
Timestamp:
09/24/06 17:50:17 (16 years ago)
Author:
jwoithe
Message:

MOTU: Fixed false "missed rx cycle" report following xrun recovery.
Ensure iso rx/tx contexts are deallocated during shutdown/xrun recovery by explicitly deleting IsoHandlers? in IsoHandlerManager::pruneHandlers(). If they aren't deleted here they never get deleted because the reference is lost.
IsoHandler? destructor should only call stop() if the handle is valid.
IsoXmitHandler?'s destructor sets the handle NULL to prevent double-free by the inherited IsoHandler? destructor.
Don't call raw1394_iso_shutdown() from our code. libraw1394 1.2.1 has a bug whereby raw1394_new_handle() fails to initialise the iso_packet_infos field. The bug hits us particularly in IsoRecvHandler::prepare(). It's also not really necessary to call raw1394_iso_shutdown() since raw1394_destroy_handle() will do any cleanups we happen to need.
MOTU: the receive stream no longer falsely complains of buffer problems during device shutdown.
MOTU: fixed a false "missed cycle" detection immediately after the stream was enabled.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/libfreebob-2.0/src/libstreaming/IsoHandler.cpp

    r267 r309  
    8181 
    8282IsoHandler::~IsoHandler() { 
    83     stop(); 
    84     if(m_handle) raw1394_destroy_handle(m_handle); 
     83    if(m_handle) { 
     84        stop(); 
     85        raw1394_destroy_handle(m_handle); 
     86    } 
    8587    if(m_handle_util) raw1394_destroy_handle(m_handle_util); 
    8688     
     
    228230IsoRecvHandler::~IsoRecvHandler() 
    229231{ 
    230         raw1394_iso_shutdown(m_handle); 
     232// Don't call until libraw1394's raw1394_new_handle() function has been 
     233// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     234// confirmed present in libraw1394 1.2.1.  In any case, 
     235// raw1394_destroy_handle() will do any iso system shutdown required. 
     236//      raw1394_iso_shutdown(m_handle); 
    231237        raw1394_destroy_handle(m_handle); 
    232  
     238        m_handle = NULL; 
    233239} 
    234240 
     
    263269bool IsoRecvHandler::prepare() 
    264270{ 
    265         raw1394_iso_shutdown(m_handle); 
     271// Don't call until libraw1394's raw1394_new_handle() function has been 
     272// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     273// confirmed present in libraw1394 1.2.1. 
     274//      raw1394_iso_shutdown(m_handle); 
    266275         
    267276        debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing iso receive handler (%p)\n",this); 
     
    330339IsoXmitHandler::~IsoXmitHandler() 
    331340{ 
    332         debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    333         raw1394_iso_shutdown(m_handle); 
     341// Don't call until libraw1394's raw1394_new_handle() function has been 
     342// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     343// confirmed present in libraw1394 1.2.1.  In any case, 
     344// raw1394_destroy_handle() will do any iso system shutdown required. 
     345//      raw1394_iso_shutdown(m_handle); 
    334346        raw1394_destroy_handle(m_handle); 
     347        m_handle = NULL; 
    335348} 
    336349 
     
    425438IsoRecvHandler::~IsoRecvHandler() 
    426439{ 
     440// Don't call until libraw1394's raw1394_new_handle() function has been 
     441// fixed to correctly initialise the iso_packet_infos field.  Bug is 
     442// confirmed present in libraw1394 1.2.1.  In any case, 
     443// raw1394_destroy_handle() (in the base class destructor) will do any iso 
     444// system shutdown required. 
    427445        raw1394_iso_shutdown(m_handle); 
    428446 
  • branches/libfreebob-2.0/src/libstreaming/IsoHandler.h

    r244 r309  
    112112                 
    113113                unsigned int getCycleCounter(); 
    114      
     114 
    115115        protected: 
    116116            raw1394handle_t m_handle; 
  • branches/libfreebob-2.0/src/libstreaming/IsoHandlerManager.cpp

    r269 r309  
    173173                } 
    174174        } 
    175  
    176175        debugFatal("Could not find handler (%p)\n", handler); 
    177176         
     
    470469                unregisterHandler(*it); 
    471470                debugOutput( DEBUG_LEVEL_VERBOSE, " deleting handler (%p)\n",*it); 
     471 
     472                // Now the handler's been unregistered it won't be reused 
     473                // again.  Therefore it really needs to be formally deleted 
     474                // to free up the raw1394 handle.  Otherwise things fall 
     475                // apart after several xrun recoveries as the system runs 
     476                // out of resources to support all the disused but still 
     477                // allocated raw1394 handles.  At least this is the current 
     478                // theory as to why we end up with "memory allocation" 
     479                // failures after several Xrun recoveries. 
     480                delete *it; 
    472481    } 
    473482 
  • branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.cpp

    r307 r309  
    113113        } 
    114114 
     115        // Similarly, initialise the "next cycle".  This can be done 
     116        // whenever iso data is seen - it doesn't have to wait until 
     117        // the stream is initialised. 
     118        if (m_next_cycle < 0) 
     119                m_next_cycle = cycle; 
     120 
    115121        // Do housekeeping expected for all packets sent to the MOTU, even 
    116122        // for packets containing no audio data. 
     
    169175        } 
    170176 
    171  
    172         if (!m_disabled) { 
     177        if  (!m_disabled) { 
    173178                if (++m_next_cycle >= 8000) 
    174179                        m_next_cycle -= 8000; 
     
    871876        unsigned int event_size) 
    872877    : ReceiveStreamProcessor(port, framerate), m_event_size(event_size), 
    873         m_last_cycle_ofs(-1), m_next_cycle(-1)
     878        m_last_cycle_ofs(-1), m_next_cycle(-1), m_closedown_active(0)
    874879 
    875880        // Set up the Delay-locked-loop to track audio frequency relative 
     
    906911    // Detect missed receive cycles 
    907912    // FIXME: it would be nice to advance the rx buffer by the amount of 
    908     // frames missed.  However, since the MOTU transmits more frames  
    909     // per cycle than the average and "catches up" with period emty 
    910     // cycles it's not trivial to work out precisely how many frames 
    911     // were missed.  Ultimately we need to do so if sync is to be  
    912     // maintained across a transient receive failure. 
     913    // frames missed.  However, since the MOTU transmits more frames per 
     914    // cycle than the average and "catches up" with periodic empty cycles 
     915    // it's not trivial to work out precisely how many frames were missed.  
     916    // Ultimately I think we need to do so if sync is to be maintained 
     917    // across a transient receive failure. 
    913918    if (m_next_cycle < 0) 
    914919        m_next_cycle = cycle; 
     
    919924        have_lost_cycles = 1; 
    920925    } 
    921     if (++m_next_cycle >= 8000) 
    922         m_next_cycle -= 8000; 
     926    if (!m_disabled) { 
     927        if (++m_next_cycle >= 8000) 
     928            m_next_cycle -= 8000; 
     929    } else 
     930        m_next_cycle = -1; 
    923931 
    924932    // If the packet length is 8 bytes (ie: just a CIP-like header) there is 
     
    983991        } 
    984992 
    985         // Don't process the stream when it is not enabled. 
     993        // Don't process the stream when it is not enabled 
    986994        if (m_disabled) { 
    987995                return RAW1394_ISO_OK; 
    988996        } 
    989997         
     998        // If closedown is active we also just throw data way, but in this case 
     999        // we keep the frame counter going to prevent a false xrun detection 
     1000        if (m_closedown_active) { 
     1001                incrementFrameCounter(n_events); 
     1002                if (m_framecounter > (signed int)m_period) 
     1003                        return RAW1394_ISO_DEFER; 
     1004                return RAW1394_ISO_OK; 
     1005        } 
     1006 
    9901007        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "put packet...\n"); 
    9911008 
     
    10651082                return false; 
    10661083        } 
     1084 
     1085        m_next_cycle = -1; 
    10671086         
    10681087        return true; 
     
    11851204        unsigned int bytes2read = m_period * m_event_size; 
    11861205 
     1206        // If closedown is in progress just pretend that data's been transferred 
     1207        // to prevent false underrun detections on the event buffer. 
     1208        if (m_closedown_active) 
     1209                return true; 
     1210 
    11871211        /* Read events2read bytes from the ringbuffer. 
    11881212        *  First see if it can be done in one read.  If so, ok. 
     
    14061430        return m_event_size; 
    14071431} 
     1432 
     1433bool MotuReceiveStreamProcessor::preparedForStop() { 
     1434 
     1435        // A MOTU receive stream can stop at any time.  However, signify 
     1436        // that stopping is in progress because other streams (notably the 
     1437        // transmit stream) may keep going for some time and cause an 
     1438        // overflow in the receive buffers.  If a closedown is in progress 
     1439        // the receive handler simply throws all incoming data away so 
     1440        // no buffer overflow can occur. 
     1441        m_closedown_active = 1; 
     1442        return true; 
     1443} 
    14081444                 
    14091445} // end of namespace FreebobStreaming 
  • branches/libfreebob-2.0/src/libstreaming/MotuStreamProcessor.h

    r305 r309  
    164164        unsigned int getEventSize(void); 
    165165 
     166        virtual bool preparedForStop(); 
     167 
    166168protected: 
    167169 
     
    187189        signed int m_next_cycle; 
    188190 
     191        // Signifies a closedown is in progress, in which case incoming data  
     192        // is junked. 
     193        signed int m_closedown_active; 
     194 
    189195    DECLARE_DEBUG_MODULE; 
    190196 
  • branches/libfreebob-2.0/src/libstreaming/StreamProcessorManager.cpp

    r291 r309  
    357357         
    358358        debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to start running...\n"); 
    359         // we have to wait untill all streamprocessors indicate that they are running 
     359        // we have to wait until all streamprocessors indicate that they are running 
    360360        // i.e. that there is actually some data stream flowing 
    361361        int wait_cycles=2000; // two seconds 
     
    516516                        } 
    517517                         
    518                          
    519518                } 
    520519 
     
    529528                         
    530529                } 
    531      
    532530         
    533531        return true;