Changeset 3901

Show
Ignore:
Timestamp:
02/05/10 09:18:58 (6 months ago)
Author:
sletz
Message:

Merge branch 'server_no_deadlock'

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • jack2/trunk/jackmp/common/JackEngine.cpp

    r3853 r3901  
    3535namespace Jack 
    3636{ 
    37  
    38 #define AssertRefnum(ref) assert(ref >= 0 && ref < CLIENT_NUM); 
    3937 
    4038JackEngine::JackEngine(JackGraphManager* manager, 
     
    214212 
    215213    // The client may be notified by the RT thread while closing 
    216     if (!client) { 
    217         jack_log("JackEngine::NotifyClient: client not available anymore"); 
    218     } else if (client->GetClientControl()->fCallback[event]) { 
    219         if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) 
    220             jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); 
    221     } else { 
    222         jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); 
    223     } 
    224 
    225  
    226 void JackEngine::NotifyClients(int event, int sync, const char*  message, int value1, int value2) 
     214    if (client) { 
     215     
     216        if (client && client->GetClientControl()->fCallback[event]) { 
     217            /* 
     218                Important for internal clients : unlock before calling the notification callbacks. 
     219            */ 
     220            bool res = fMutex.Unlock(); 
     221            if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) 
     222                jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); 
     223            if (res) 
     224                fMutex.Lock(); 
     225        
     226        } else { 
     227            jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); 
     228        } 
     229    } 
     230
     231 
     232void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) 
    227233{ 
    228234    for (int i = 0; i < CLIENT_NUM; i++) { 
    229         JackClientInterface* client = fClientTable[i]; 
    230         if (client) { 
    231             if (client->GetClientControl()->fCallback[event]) { 
    232                 if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) 
    233                     jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); 
    234             } else { 
    235                 jack_log("JackEngine::NotifyClients: no callback for event = %ld", event); 
    236             } 
    237         } 
     235        NotifyClient(i, event, sync, message, value1, value2); 
    238236    } 
    239237} 
     
    275273{ 
    276274    // Use the audio thread => request thread communication channel 
    277     fEngineControl->ResetFrameTime(callback_usecs); 
    278     fEngineControl->NotifyXRun(delayed_usecs); 
     275    fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); 
    279276    fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); 
    280277} 
     
    349346int JackEngine::GetInternalClientName(int refnum, char* name_res) 
    350347{ 
    351     AssertRefnum(refnum); 
    352348    JackClientInterface* client = fClientTable[refnum]; 
    353     if (client) { 
    354         strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); 
    355         return 0; 
    356     } else { 
    357         return -1; 
    358     } 
     349    strncpy(name_res, client->GetClientControl()->fName, JACK_CLIENT_NAME_SIZE); 
     350    return 0; 
    359351} 
    360352 
     
    379371int JackEngine::InternalClientUnload(int refnum, int* status) 
    380372{ 
    381     AssertRefnum(refnum); 
    382373    JackClientInterface* client = fClientTable[refnum]; 
    383374    if (client) { 
     
    593584int JackEngine::ClientExternalClose(int refnum) 
    594585{ 
    595     AssertRefnum(refnum); 
    596586    JackClientInterface* client = fClientTable[refnum]; 
    597  
    598     if (client) { 
    599         fEngineControl->fTransport.ResetTimebase(refnum); 
    600         int res = ClientCloseAux(refnum, client, true); 
    601         client->Close(); 
    602         delete client; 
    603         return res; 
    604     } else { 
    605         return -1; 
    606     } 
     587    fEngineControl->fTransport.ResetTimebase(refnum); 
     588    int res = ClientCloseAux(refnum, client, true); 
     589    client->Close(); 
     590    delete client; 
     591    return res; 
    607592} 
    608593 
     
    610595int JackEngine::ClientInternalClose(int refnum, bool wait) 
    611596{ 
    612     AssertRefnum(refnum); 
    613597    JackClientInterface* client = fClientTable[refnum]; 
    614     return (client)    ? ClientCloseAux(refnum, client, wait) : -1
     598    return ClientCloseAux(refnum, client, wait)
    615599} 
    616600 
     
    657641int JackEngine::ClientActivate(int refnum, bool is_real_time) 
    658642{ 
    659     AssertRefnum(refnum); 
    660643    JackClientInterface* client = fClientTable[refnum]; 
    661     assert(fClientTable[refnum]); 
    662  
    663644    jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); 
     645     
    664646    if (is_real_time) 
    665647        fGraphManager->Activate(refnum); 
     
    678660int JackEngine::ClientDeactivate(int refnum) 
    679661{ 
    680     AssertRefnum(refnum); 
    681662    JackClientInterface* client = fClientTable[refnum]; 
    682     if (client == NULL) 
    683         return -1; 
    684  
    685663    jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); 
    686664 
     
    718696{ 
    719697    jack_log("JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d", refnum, name, type, flags, buffer_size); 
    720     AssertRefnum(refnum); 
    721     assert(fClientTable[refnum]); 
    722  
     698  
    723699    // Check if port name already exists 
    724700    if (fGraphManager->GetPort(name) != NO_PORT) { 
     
    739715{ 
    740716    jack_log("JackEngine::PortUnRegister ref = %ld port_index = %ld", refnum, port_index); 
    741     AssertRefnum(refnum); 
    742     assert(fClientTable[refnum]); 
    743  
     717  
    744718    // Disconnect port ==> notification is sent 
    745719    PortDisconnect(refnum, port_index, ALL_PORTS); 
     
    756730{ 
    757731    jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); 
    758     AssertRefnum(refnum); 
    759732    jack_port_id_t port_src, port_dst; 
    760733 
     
    767740{ 
    768741    jack_log("JackEngine::PortConnect src = %d dst = %d", src, dst); 
    769     AssertRefnum(refnum); 
    770742    JackClientInterface* client; 
    771743    int ref; 
     
    803775{ 
    804776    jack_log("JackEngine::PortDisconnect src = %s dst = %s", src, dst); 
    805     AssertRefnum(refnum); 
    806777    jack_port_id_t port_src, port_dst; 
    807778 
     
    814785{ 
    815786    jack_log("JackEngine::PortDisconnect src = %d dst = %d", src, dst); 
    816     AssertRefnum(refnum); 
    817  
     787  
    818788    if (dst == ALL_PORTS) { 
    819789 
     
    851821int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) 
    852822{ 
    853     AssertRefnum(refnum); 
    854823    char old_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; 
    855824    strcpy(old_name, fGraphManager->GetPort(port)->GetName()); 
  • jack2/trunk/jackmp/common/JackEngine.h

    r3853 r3901  
    2424#include "JackGraphManager.h" 
    2525#include "JackSynchro.h" 
     26#include "JackMutex.h" 
    2627#include "JackTransportEngine.h" 
    2728#include "JackPlatformPlug.h" 
     
    3839*/ 
    3940 
    40 class SERVER_EXPORT JackEngine  
     41class SERVER_EXPORT JackEngine : public JackLockAble 
    4142{ 
     43    friend class JackLockedEngine; 
     44     
    4245    private: 
    4346 
     
    7275        void NotifyPortRename(jack_port_id_t src, const char* old_name); 
    7376        void NotifyActivate(int refnum); 
     77         
     78        bool CheckClient(int refnum) 
     79        { 
     80            return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); 
     81        } 
    7482 
    7583    public: 
  • jack2/trunk/jackmp/common/JackEngineControl.cpp

    r3526 r3901  
    8282} 
    8383     
    84 void JackEngineControl::NotifyXRun(float delayed_usecs) 
     84void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) 
    8585{ 
     86    ResetFrameTime(callback_usecs); 
    8687    fXrunDelayedUsecs = delayed_usecs; 
    8788    if (delayed_usecs > fMaxDelayedUsecs) 
  • jack2/trunk/jackmp/common/JackEngineControl.h

    r3782 r3901  
    163163     
    164164    // XRun 
    165     void NotifyXRun(float delayed_usecs); 
     165    void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); 
    166166    void ResetXRun() 
    167167    { 
  • jack2/trunk/jackmp/common/JackLockedEngine.h

    r3853 r3901  
    3838    // Assuming thread cancellation, must rethrow 
    3939    throw; 
    40      
    4140} 
    4241*/ 
     
    6362    }                                               \ 
    6463 
     64 
    6565/*! 
    6666\brief Locked Engine, access to methods is serialized using a mutex. 
    6767*/ 
    6868 
    69 class SERVER_EXPORT JackLockedEngine : public JackLockAble 
     69class SERVER_EXPORT JackLockedEngine  
    7070{ 
    7171    private: 
     
    100100        { 
    101101            TRY_CALL 
    102             JackLock lock(this); 
     102            JackLock lock(&fEngine); 
    103103            return fEngine.ClientCheck(name, name_res, protocol, options, status); 
    104104            CATCH_EXCEPTION_RETURN 
     
    107107        { 
    108108            TRY_CALL 
    109             JackLock lock(this); 
     109            JackLock lock(&fEngine); 
    110110            return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); 
    111111            CATCH_EXCEPTION_RETURN 
     
    114114        { 
    115115            TRY_CALL 
    116             JackLock lock(this); 
     116            JackLock lock(&fEngine); 
    117117            return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); 
    118118            CATCH_EXCEPTION_RETURN 
     
    122122        { 
    123123            TRY_CALL 
    124             JackLock lock(this); 
    125             return fEngine.ClientExternalClose(refnum)
     124            JackLock lock(&fEngine); 
     125            return (fEngine.CheckClient(refnum)) ? fEngine.ClientExternalClose(refnum) : - 1
    126126            CATCH_EXCEPTION_RETURN 
    127127        } 
     
    129129        { 
    130130            TRY_CALL 
    131             JackLock lock(this); 
    132             return fEngine.ClientInternalClose(refnum, wait)
     131            JackLock lock(&fEngine); 
     132            return (fEngine.CheckClient(refnum)) ? fEngine.ClientInternalClose(refnum, wait) : -1
    133133            CATCH_EXCEPTION_RETURN 
    134134        } 
     
    137137        { 
    138138            TRY_CALL 
    139             JackLock lock(this); 
    140             return fEngine.ClientActivate(refnum, is_real_time)
     139            JackLock lock(&fEngine); 
     140            return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1
    141141            CATCH_EXCEPTION_RETURN 
    142142        } 
     
    144144        { 
    145145            TRY_CALL 
    146             JackLock lock(this); 
    147             return fEngine.ClientDeactivate(refnum)
     146            JackLock lock(&fEngine); 
     147            return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1
    148148            CATCH_EXCEPTION_RETURN 
    149149        } 
     
    153153        { 
    154154            TRY_CALL 
    155             JackLock lock(this); 
     155            JackLock lock(&fEngine); 
    156156            return fEngine.GetInternalClientName(int_ref, name_res); 
    157157            CATCH_EXCEPTION_RETURN 
     
    160160        { 
    161161            TRY_CALL 
    162             JackLock lock(this); 
     162            JackLock lock(&fEngine); 
    163163            return fEngine.InternalClientHandle(client_name, status, int_ref); 
    164164            CATCH_EXCEPTION_RETURN 
     
    167167        { 
    168168            TRY_CALL 
    169             JackLock lock(this); 
     169            JackLock lock(&fEngine); 
     170            // Client is tested in fEngine.InternalClientUnload 
    170171            return fEngine.InternalClientUnload(refnum, status); 
    171172            CATCH_EXCEPTION_RETURN 
     
    176177        { 
    177178            TRY_CALL 
    178             JackLock lock(this); 
    179             return fEngine.PortRegister(refnum, name, type, flags, buffer_size, port)
     179            JackLock lock(&fEngine); 
     180            return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1
    180181            CATCH_EXCEPTION_RETURN 
    181182        } 
     
    183184        { 
    184185            TRY_CALL 
    185             JackLock lock(this); 
    186             return fEngine.PortUnRegister(refnum, port)
     186            JackLock lock(&fEngine); 
     187            return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1
    187188            CATCH_EXCEPTION_RETURN 
    188189        } 
     
    191192        { 
    192193            TRY_CALL 
    193             JackLock lock(this); 
    194             return fEngine.PortConnect(refnum, src, dst)
     194            JackLock lock(&fEngine); 
     195            return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1
    195196            CATCH_EXCEPTION_RETURN 
    196197        } 
     
    198199        { 
    199200            TRY_CALL 
    200             JackLock lock(this); 
    201             return fEngine.PortDisconnect(refnum, src, dst)
     201            JackLock lock(&fEngine); 
     202            return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1
    202203            CATCH_EXCEPTION_RETURN 
    203204        } 
     
    206207        { 
    207208            TRY_CALL 
    208             JackLock lock(this); 
    209             return fEngine.PortConnect(refnum, src, dst)
     209            JackLock lock(&fEngine); 
     210            return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1
    210211            CATCH_EXCEPTION_RETURN 
    211212        } 
     
    213214        { 
    214215            TRY_CALL 
    215             JackLock lock(this); 
    216             return fEngine.PortDisconnect(refnum, src, dst)
     216            JackLock lock(&fEngine); 
     217            return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1
    217218            CATCH_EXCEPTION_RETURN 
    218219        } 
     
    221222        { 
    222223            TRY_CALL 
    223             JackLock lock(this); 
    224             return fEngine.PortRename(refnum, port, name)
     224            JackLock lock(&fEngine); 
     225            return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1
    225226            CATCH_EXCEPTION_RETURN 
    226227        } 
     
    242243        void NotifyXRun(int refnum) 
    243244        { 
    244             TRY_CALL 
    245             JackLock lock(this); 
     245            // RT : no lock 
    246246            fEngine.NotifyXRun(refnum); 
    247             CATCH_EXCEPTION 
    248         } 
     247        } 
     248         
    249249        void NotifyGraphReorder() 
    250250        { 
    251251            TRY_CALL 
    252             JackLock lock(this); 
     252            JackLock lock(&fEngine); 
    253253            fEngine.NotifyGraphReorder(); 
    254254            CATCH_EXCEPTION 
     
    257257        { 
    258258            TRY_CALL 
    259             JackLock lock(this); 
     259            JackLock lock(&fEngine); 
    260260            fEngine.NotifyBufferSize(buffer_size); 
    261261            CATCH_EXCEPTION 
     
    264264        { 
    265265            TRY_CALL 
    266             JackLock lock(this); 
     266            JackLock lock(&fEngine); 
    267267            fEngine.NotifySampleRate(sample_rate); 
    268268            CATCH_EXCEPTION 
     
    271271        { 
    272272            TRY_CALL 
    273             JackLock lock(this); 
     273            JackLock lock(&fEngine); 
    274274            fEngine.NotifyFreewheel(onoff); 
    275275            CATCH_EXCEPTION 
     
    279279        { 
    280280            TRY_CALL 
    281             JackLock lock(this); 
     281            JackLock lock(&fEngine); 
    282282            fEngine.NotifyFailure(code, reason); 
    283283            CATCH_EXCEPTION 
     
    287287        { 
    288288            TRY_CALL 
    289             JackLock lock(this); 
     289            JackLock lock(&fEngine); 
    290290            return fEngine.GetClientPID(name); 
    291291            CATCH_EXCEPTION_RETURN 
     
    295295        { 
    296296            TRY_CALL 
    297             JackLock lock(this); 
     297            JackLock lock(&fEngine); 
    298298            return fEngine.GetClientRefNum(name); 
    299299            CATCH_EXCEPTION_RETURN 
     
    303303        { 
    304304            TRY_CALL 
    305             JackLock lock(this); 
     305            JackLock lock(&fEngine); 
    306306            return fEngine.NotifyQuit(); 
    307307            CATCH_EXCEPTION 
  • jack2/trunk/jackmp/common/JackMutex.h

    r2907 r3901  
    3737{ 
    3838 
    39     private
    40  
     39    protected
     40     
    4141        JackMutex fMutex; 
    42  
    43     protected: 
    4442 
    4543        JackLockAble() 
  • jack2/trunk/jackmp/posix/JackPosixMutex.h

    r3665 r3901  
    104104        } 
    105105 
    106         void Lock() 
     106        bool Lock() 
    107107        { 
    108108            int res = pthread_mutex_lock(&fMutex); 
    109109            if (res != 0) 
    110110                jack_error("JackPosixMutex::Lock res = %d", res); 
     111            return (res == 0); 
    111112        } 
    112113 
     
    116117        } 
    117118 
    118         void Unlock() 
     119        bool Unlock() 
    119120        { 
    120121            int res = pthread_mutex_unlock(&fMutex); 
    121122            if (res != 0) 
    122123                jack_error("JackPosixMutex::Unlock res = %d", res); 
     124            return (res == 0); 
    123125        } 
    124126