Ignore:
Timestamp:
Apr 7, 2010 10:24:41 AM (15 years ago)
Author:
nanang
Message:

Ticket #1055: Fixed infinite loop in stopping APS after initialization failed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp

    r3116 r3134  
    4545#define BITS_PER_SAMPLE                 16 
    4646 
     47 
    4748#if 1 
    4849#   define TRACE_(st) PJ_LOG(3, st) 
     
    414415    TInt InitRecL(); 
    415416    TInt StartStreamL(); 
     417    void Deinit(); 
    416418 
    417419    // Inherited from MQueueHandlerObserver 
     
    420422    virtual void NotifyError(const TInt aError); 
    421423 
     424    TBool                        session_opened; 
    422425    State                        state_; 
    423426    struct aps_stream           *parentStrm_; 
     
    430433    RMsgQueue<TAPSCommBuffer>    iReadQ; 
    431434    RMsgQueue<TAPSCommBuffer>    iReadCommQ; 
     435    TBool                        readq_opened; 
    432436    RMsgQueue<TAPSCommBuffer>    iWriteQ; 
    433437    RMsgQueue<TAPSCommBuffer>    iWriteCommQ; 
     438    TBool                        writeq_opened; 
    434439 
    435440    CQueueHandler               *iPlayCommHandler; 
     
    461466                               const CPjAudioSetting &setting) 
    462467      : MQueueHandlerObserver(rec_cb, play_cb, user_data), 
     468        session_opened(EFalse), 
    463469        state_(STATE_NULL), 
    464470        parentStrm_(parent_strm), 
    465471        setting_(setting), 
     472        readq_opened(EFalse), 
     473        writeq_opened(EFalse), 
    466474        iPlayCommHandler(0), 
    467475        iRecCommHandler(0), 
     
    472480CPjAudioEngine::~CPjAudioEngine() 
    473481{ 
    474     Stop(); 
    475  
    476     delete iRecHandler; 
    477     delete iPlayCommHandler; 
    478     delete iRecCommHandler; 
    479  
    480     // On some devices, immediate closing after stopping may cause APS server 
    481     // panic KERN-EXEC 0, so let's wait for sometime before really closing 
    482     // the client session. 
    483     TTime start, now; 
    484     enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */ 
    485      
    486     start.UniversalTime(); 
    487     do { 
    488         pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME); 
    489         now.UniversalTime(); 
    490     } while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000); 
    491  
    492     iSession.Close(); 
    493  
    494     if (state_ == STATE_READY) { 
    495         if (parentStrm_->param.dir != PJMEDIA_DIR_PLAYBACK) { 
    496             iReadQ.Close(); 
    497             iReadCommQ.Close(); 
    498         } 
    499         iWriteQ.Close(); 
    500         iWriteCommQ.Close(); 
    501     } 
    502      
     482    Deinit(); 
     483 
    503484    TRACE_((THIS_FILE, "Sound device destroyed")); 
    504485} 
     
    508489    TInt err = iSession.InitializePlayer(iPlaySettings); 
    509490    if (err != KErrNone) { 
     491        Deinit(); 
    510492        snd_perror("Failed to initialize player", err); 
    511493        return err; 
     
    522504    while (iWriteCommQ.OpenGlobal(buf3)) 
    523505        User::After(10); 
     506         
     507    writeq_opened = ETrue; 
    524508 
    525509    // Construct message queue handler 
     
    538522    TInt err = iSession.InitializeRecorder(iRecSettings); 
    539523    if (err != KErrNone && err != KErrAlreadyExists) { 
     524        Deinit(); 
    540525        snd_perror("Failed to initialize recorder", err); 
    541526        return err; 
     
    554539        User::After(10); 
    555540 
     541    readq_opened = ETrue; 
     542 
    556543    // Construct message queue handlers 
    557544    iRecHandler = CQueueHandler::NewL(this, &iReadQ, NULL, 
     
    574561    PJ_ASSERT_RETURN(state_ == STATE_NULL, PJMEDIA_EAUD_INVOP); 
    575562     
     563    if (!session_opened) { 
     564        TInt err = iSession.Connect(); 
     565        if (err != KErrNone) 
     566            return err; 
     567        session_opened = ETrue; 
     568    } 
     569 
    576570    // Even if only capturer are opened, playback thread of APS Server need 
    577571    // to be run(?). Since some messages will be delivered via play comm queue. 
     
    593587         
    594588        // Then wait until initialization done. 
    595         while (state_ != STATE_READY) 
     589        while (state_ != STATE_READY && state_ != STATE_NULL) 
    596590            pj_symbianos_poll(-1, 100); 
    597591    } 
     
    618612 
    619613    User::LeaveIfError(iSession.Connect()); 
     614    session_opened = ETrue; 
    620615} 
    621616 
     
    648643} 
    649644 
     645void CPjAudioEngine::Deinit() 
     646{ 
     647    Stop(); 
     648 
     649    delete iRecHandler; 
     650    delete iPlayCommHandler; 
     651    delete iRecCommHandler; 
     652 
     653    if (session_opened) { 
     654        TTime start, now; 
     655        enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */ 
     656         
     657        // On some devices, immediate closing after stopping may cause  
     658        // APS server panic KERN-EXEC 0, so let's wait for sometime before 
     659        // closing the client session. 
     660        start.UniversalTime(); 
     661        do { 
     662            pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME); 
     663            now.UniversalTime(); 
     664        } while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000); 
     665 
     666        iSession.Close(); 
     667        session_opened = EFalse; 
     668    } 
     669 
     670    if (readq_opened) { 
     671        iReadQ.Close(); 
     672        iReadCommQ.Close(); 
     673        readq_opened = EFalse; 
     674    } 
     675 
     676    if (writeq_opened) { 
     677        iWriteQ.Close(); 
     678        iWriteCommQ.Close(); 
     679        writeq_opened = EFalse; 
     680    } 
     681 
     682    state_ = STATE_NULL; 
     683} 
     684 
    650685void CPjAudioEngine::InputStreamInitialized(const TInt aStatus) 
    651686{ 
     
    659694            state_ = STATE_READY; 
    660695        } 
     696    } else { 
     697        Deinit(); 
    661698    } 
    662699} 
     
    676713        } else 
    677714            InitRecL(); 
     715    } else { 
     716        Deinit(); 
    678717    } 
    679718} 
     
    681720void CPjAudioEngine::NotifyError(const TInt aError) 
    682721{ 
     722    Deinit(); 
    683723    snd_perror("Error from CQueueHandler", aError); 
    684724} 
Note: See TracChangeset for help on using the changeset viewer.