Ignore:
Timestamp:
Nov 29, 2019 4:21:17 AM (5 years ago)
Author:
ming
Message:

Fixed #2251: Deadlock between PJSUA LOCK and conference mutex

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/third_party/mp3/mp3_writer.c

    r4483 r6112  
    6262    pj_size_t       cb_size; 
    6363    pj_status_t    (*cb)(pjmedia_port*, void*); 
     64    pj_bool_t        subscribed; 
     65    pj_bool_t        cb_called; 
     66    void           (*cb2)(pjmedia_port*, void*); 
    6467 
    6568    unsigned        silence_duration; 
     
    332335 
    333336 
    334  
     337#if !DEPRECATED_FOR_TICKET_2251 
    335338/* 
    336339 * Register callback. 
     
    351354    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP); 
    352355 
     356    PJ_LOG(1, (THIS_FILE, "pjmedia_mp3_writer_port_set_cb() is deprecated. " 
     357               "Use pjmedia_mp3_writer_port_set_cb2() instead.")); 
     358 
    353359    fport = (struct mp3_file_port*) port; 
    354360 
     
    359365    return PJ_SUCCESS; 
    360366 
     367} 
     368#endif 
     369 
     370 
     371/* 
     372 * Register callback. 
     373 */ 
     374PJ_DEF(pj_status_t)  
     375pjmedia_mp3_writer_port_set_cb2(pjmedia_port *port, 
     376                                pj_size_t pos, 
     377                                void *user_data, 
     378                                void (*cb)(pjmedia_port *port, 
     379                                           void *usr_data)) 
     380{ 
     381    struct mp3_file_port *fport; 
     382 
     383    /* Sanity check */ 
     384    PJ_ASSERT_RETURN(port && cb, PJ_EINVAL); 
     385 
     386    /* Check that this is really a writer port */ 
     387    PJ_ASSERT_RETURN(port->info.signature == SIGNATURE, PJ_EINVALIDOP); 
     388 
     389    fport = (struct mp3_file_port*) port; 
     390 
     391    fport->cb_size = pos; 
     392    fport->base.port_data.pdata = user_data; 
     393    fport->cb2 = cb; 
     394    fport->cb_called = PJ_FALSE; 
     395 
     396    return PJ_SUCCESS; 
     397 
     398} 
     399 
     400 
     401static pj_status_t file_on_event(pjmedia_event *event, 
     402                                 void *user_data) 
     403{ 
     404    struct file_port *fport = (struct file_port*)user_data; 
     405 
     406    if (event->type == PJMEDIA_EVENT_CALLBACK) { 
     407        if (fport->cb2) 
     408            (*fport->cb2)(&fport->base, fport->base.port_data.pdata); 
     409    } 
     410     
     411    return PJ_SUCCESS; 
    361412} 
    362413 
     
    499550    } 
    500551 
    501     /* Increment total written, and check if we need to call callback */ 
    502      
    503     if (fport->cb && fport->total >= fport->cb_size) { 
    504         pj_status_t (*cb)(pjmedia_port*, void*); 
    505         pj_status_t status; 
    506  
    507         cb = fport->cb; 
    508         fport->cb = NULL; 
    509  
    510         status = (*cb)(this_port, this_port->port_data.pdata); 
    511         return status; 
     552    /* Check if we need to call callback */ 
     553    if (fport->total >= fport->cb_size) { 
     554        if (fport->cb2) { 
     555            if (!fport->subscribed) { 
     556                pj_status_t status; 
     557 
     558                status = pjmedia_event_subscribe(NULL, &file_on_event, 
     559                                                 fport, fport); 
     560                fport->subscribed = (status == PJ_SUCCESS)? PJ_TRUE: 
     561                                    PJ_FALSE; 
     562            } 
     563 
     564            if (fport->subscribed && !fport->cb_called) { 
     565                pjmedia_event event; 
     566 
     567                /* To prevent the callback from being called more than once. */ 
     568                fport->cb_called = PJ_TRUE; 
     569 
     570                pjmedia_event_init(&event, PJMEDIA_EVENT_CALLBACK, 
     571                                   NULL, fport); 
     572                pjmedia_event_publish(NULL, fport, &event, 
     573                                      PJMEDIA_EVENT_PUBLISH_POST_EVENT); 
     574            } 
     575        } else if (fport->cb) { 
     576            pj_status_t (*cb)(pjmedia_port*, void*); 
     577            pj_status_t status; 
     578 
     579            cb = fport->cb; 
     580            fport->cb = NULL; 
     581 
     582            status = (*cb)(this_port, this_port->port_data.pdata); 
     583            return status; 
     584        } 
    512585    } 
    513586 
     
    537610    unsigned long MP3Err; 
    538611 
     612    if (fport->subscribed) { 
     613        pjmedia_event_unsubscribe(NULL, &file_on_event, fport, fport); 
     614        fport->subscribed = PJ_FALSE; 
     615    } 
    539616 
    540617    /* Close encoder */ 
Note: See TracChangeset for help on using the changeset viewer.