Changeset 841

Show
Ignore:
Timestamp:
01/13/08 09:17:58 (13 years ago)
Author:
ppalmers
Message:

fix single ISO thread operation (1394 stack seems to be thread-unsafe)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r833 r841  
    191191    if(m_Client) { 
    192192        bool result = m_Client->tryWaitForSignal(); 
    193         //debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " returns %d\n", result); 
     193        //debugOutput(DEBUG_LEVEL_VERBOSE, " returns %d\n", result); 
    194194        return result; 
    195195    } else { 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r833 r841  
    9898{ 
    9999    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "updating shadow vars...\n"); 
    100     unsigned int i; 
    101     m_poll_nfds_shadow = m_IsoHandlers.size(); 
    102     if(m_poll_nfds_shadow > ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT) { 
    103         debugWarning("Too much ISO Handlers in manager...\n"); 
    104         m_poll_nfds_shadow = ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT; 
    105     } 
    106     for (i = 0; i < m_poll_nfds_shadow; i++) { 
     100    unsigned int i, cnt, max; 
     101    max = m_IsoHandlers.size(); 
     102    for (i = 0, cnt = 0; i < max; i++) { 
    107103        IsoHandler *h = m_IsoHandlers.at(i); 
    108104        assert(h); 
    109         m_IsoHandler_map_shadow[i] = h; 
    110  
    111         m_poll_fds_shadow[i].fd = h->getFileDescriptor(); 
    112         m_poll_fds_shadow[i].revents = 0; 
    113105        if (h->isEnabled()) { 
    114             m_poll_fds_shadow[i].events = POLLIN; 
    115         } else { 
    116             m_poll_fds_shadow[i].events = 0; 
    117         } 
    118     } 
     106            // receive handlers are always poll'ed 
     107            // transmit handlers only when the client is ready 
     108            if (h->getType() == IsoHandler::eHT_Receive || h->tryWaitForClient()) { 
     109                m_IsoHandler_map_shadow[cnt] = h; 
     110                m_poll_fds_shadow[cnt].fd = h->getFileDescriptor(); 
     111                m_poll_fds_shadow[cnt].revents = 0; 
     112                m_poll_fds_shadow[cnt].events = POLLIN; 
     113                cnt++; 
     114            } else { 
     115                debugOutput(DEBUG_LEVEL_VERBOSE, "skipped handler %p\n", h); 
     116            } 
     117        } 
     118        if(cnt > ISOHANDLERMANAGER_MAX_ISO_HANDLERS_PER_PORT) { 
     119            debugWarning("Too much ISO Handlers in manager...\n"); 
     120            break; 
     121        } 
     122    } 
     123    m_poll_nfds_shadow = cnt; 
    119124    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, " updated shadow vars...\n"); 
    120125} 
     
    143148    // bypass if no handlers are registered 
    144149    if (m_poll_nfds_shadow == 0) { 
    145         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "bypass iterate since no handlers registered\n"); 
     150        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "bypass iterate since no handlers to poll\n"); 
    146151        usleep(m_poll_timeout * 1000); 
    147152        return true; 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r839 r841  
    207207 
    208208void 
    209 StreamProcessor::setSyncDelay(int d) { 
    210     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "Setting SP %p SyncDelay to %d ticks\n", this, d); 
    211     m_sync_delay = d; 
     209StreamProcessor::setSyncDelay(unsigned int d) { 
     210    unsigned int frames = d / getTicksPerFrame(); 
     211    debugOutput(DEBUG_LEVEL_VERBOSE, "Setting SP %p SyncDelay to %u ticks, %u frames\n", this, d, frames); 
     212    m_sync_delay = d; // FIXME: sync delay not necessary anymore 
    212213} 
    213214 
     
    273274    #ifdef DEBUG 
    274275    if (!can_transfer) { 
    275         debugWarning("(%p, %s) cannot transfer since fc == %u, nbframes == %u\n",  
     276        debugOutput(DEBUG_LEVEL_VERBOSE, "(%p, %s) cannot transfer since fc == %u, nbframes == %u\n",  
    276277            this, ePTToString(getType()), fc, nbframes); 
    277278    } 
     
    913914    int result; 
    914915    if(m_state == ePS_Running && m_next_state == ePS_Running) { 
     916        // check whether we already fullfil the criterion 
     917        unsigned int bufferfill = m_data_buffer->getBufferFill(); 
     918        if(bufferfill >= m_signal_period + m_signal_offset) { 
     919            return true; 
     920        } 
     921 
    915922        result = sem_wait(&m_signal_semaphore); 
    916923#ifdef DEBUG 
     
    931938StreamProcessor::tryWaitForSignal() 
    932939{ 
    933     if(m_state == ePS_Running) { 
    934         return sem_trywait(&m_signal_semaphore) == 0; 
     940    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "(%p, %s) trywait ...\n", this, getTypeString()); 
     941    int result; 
     942    if(m_state == ePS_Running && m_next_state == ePS_Running) { 
     943        // check whether we already fullfil the criterion 
     944        unsigned int bufferfill = m_data_buffer->getBufferFill(); 
     945        if(bufferfill >= m_signal_period + m_signal_offset) { 
     946            return true; 
     947        } 
     948 
     949        result = sem_trywait(&m_signal_semaphore); 
     950#ifdef DEBUG 
     951        int tmp; 
     952        sem_getvalue(&m_signal_semaphore, &tmp); 
     953        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " sem_wait returns: %d, sem_value: %d\n", result, tmp); 
     954#endif 
     955        return result == 0; 
    935956    } else { 
    936957        // when we're not running, we can always provide frames 
    937         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Not running...\n"); 
     958        // when we're in a state transition, keep iterating too 
     959        debugOutput(DEBUG_LEVEL_VERBOSE, "Not running...\n"); 
    938960        return true; 
    939961    } 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r833 r841  
    111111    bool isStopped() 
    112112            {return m_state == ePS_Stopped;}; 
     113    bool isWaitingForStream() 
     114            {return m_state == ePS_WaitingForStream;}; 
    113115 
    114116    // these schedule and wait for the state transition 
     
    406408         * @return the sync delay 
    407409         */ 
    408         int getSyncDelay() {return m_sync_delay;}; 
     410        unsigned int getSyncDelay() {return m_sync_delay;}; 
    409411        /** 
    410412         * sets the sync delay 
    411413         * @param d sync delay 
    412414         */ 
    413         void setSyncDelay(int d); 
     415        void setSyncDelay(unsigned int d); 
    414416 
    415417        /** 
     
    488490        float m_ticks_per_frame; 
    489491        int m_last_cycle; 
    490         int m_sync_delay; 
     492        unsigned int m_sync_delay; 
    491493    private: 
    492494        bool m_in_xrun; 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r840 r841  
    561561        } 
    562562    } 
    563     // wait for the SP's to get into the dry-running state 
     563    // wait for the SP's to get into the dry-running/stopped state 
    564564    int cnt = 2000; 
    565565    bool ready = false; 
     
    569569            it != m_ReceiveProcessors.end(); 
    570570            ++it ) { 
    571             ready &= ((*it)->isDryRunning() || (*it)->isStopped()); 
     571            ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream()); 
    572572        } 
    573573        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    574574            it != m_TransmitProcessors.end(); 
    575575            ++it ) { 
    576             ready &= ((*it)->isDryRunning() || (*it)->isStopped()); 
     576            ready &= ((*it)->isDryRunning() || (*it)->isStopped() || (*it)->isWaitingForStream()); 
    577577        } 
    578578        SleepRelativeUsec(125); 
     
    717717        } 
    718718 
    719         unsigned int bufferfill = m_SyncSource->getBufferFill(); 
    720         period_not_ready = bufferfill < m_period; 
    721  
    722 #ifdef DEBUG 
    723         if(period_not_ready) { 
    724             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "period is not ready (bufferfill: %u)\n", bufferfill); 
    725         } else { 
    726             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "period is ready (bufferfill: %u)\n", bufferfill); 
    727         } 
    728 #endif 
    729  
     719        // HACK: this should be solved more elegantly 
     720        period_not_ready = false; 
     721        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     722            it != m_ReceiveProcessors.end(); 
     723            ++it ) { 
     724            bool this_sp_period_ready = (*it)->canClientTransferFrames(m_period); 
     725            if (!this_sp_period_ready) { 
     726                period_not_ready = true; 
     727            } 
     728        } 
    730729        // check for underruns on the ISO side, 
    731730        // those should make us bail out of the wait loop