@@ -627,10 +627,8 @@ void MediaServerList::removeServer( const std::string& udn )
627
627
/*
628
628
* Handles servers listing UPnP events
629
629
*/
630
- int MediaServerList::Callback ( Upnp_EventType event_type, void * p_event, MediaServerList* self )
630
+ int MediaServerList::Callback ( Upnp_EventType event_type, void * p_event )
631
631
{
632
- services_discovery_t * p_sd = self->m_sd ;
633
-
634
632
switch ( event_type )
635
633
{
636
634
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
@@ -642,14 +640,24 @@ int MediaServerList::Callback( Upnp_EventType event_type, void* p_event, MediaSe
642
640
643
641
int i_res;
644
642
i_res = UpnpDownloadXmlDoc ( p_discovery->Location , &p_description_doc );
643
+
644
+ MediaServerList *self = UpnpInstanceWrapper::lockMediaServerList ();
645
+ if ( !self )
646
+ {
647
+ UpnpInstanceWrapper::unlockMediaServerList ();
648
+ return UPNP_E_CANCELED;
649
+ }
650
+
645
651
if ( i_res != UPNP_E_SUCCESS )
646
652
{
647
- msg_Warn ( p_sd , " Could not download device description! "
653
+ msg_Warn ( self-> m_sd , " Could not download device description! "
648
654
" Fetching data from %s failed: %s" ,
649
655
p_discovery->Location , UpnpGetErrorMessage ( i_res ) );
656
+ UpnpInstanceWrapper::unlockMediaServerList ();
650
657
return i_res;
651
658
}
652
659
self->parseNewServer ( p_description_doc, p_discovery->Location );
660
+ UpnpInstanceWrapper::unlockMediaServerList ();
653
661
ixmlDocument_free ( p_description_doc );
654
662
}
655
663
break ;
@@ -658,16 +666,29 @@ int MediaServerList::Callback( Upnp_EventType event_type, void* p_event, MediaSe
658
666
{
659
667
struct Upnp_Discovery * p_discovery = ( struct Upnp_Discovery * )p_event;
660
668
661
- self->removeServer ( p_discovery->DeviceId );
669
+ MediaServerList *self = UpnpInstanceWrapper::lockMediaServerList ();
670
+ if ( self )
671
+ self->removeServer ( p_discovery->DeviceId );
672
+ UpnpInstanceWrapper::unlockMediaServerList ();
662
673
}
663
674
break ;
664
675
665
676
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
666
- msg_Warn ( p_sd, " subscription complete" );
677
+ {
678
+ MediaServerList *self = UpnpInstanceWrapper::lockMediaServerList ();
679
+ if ( self )
680
+ msg_Warn ( self->m_sd , " subscription complete" );
681
+ UpnpInstanceWrapper::unlockMediaServerList ();
682
+ }
667
683
break ;
668
684
669
685
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
670
- msg_Warn ( p_sd, " search timeout" );
686
+ {
687
+ MediaServerList *self = UpnpInstanceWrapper::lockMediaServerList ();
688
+ if ( self )
689
+ msg_Warn ( self->m_sd , " search timeout" );
690
+ UpnpInstanceWrapper::unlockMediaServerList ();
691
+ }
671
692
break ;
672
693
673
694
case UPNP_EVENT_RECEIVED:
@@ -677,7 +698,12 @@ int MediaServerList::Callback( Upnp_EventType event_type, void* p_event, MediaSe
677
698
break ;
678
699
679
700
default :
680
- msg_Err ( p_sd, " Unhandled event, please report ( type=%d )" , event_type );
701
+ {
702
+ MediaServerList *self = UpnpInstanceWrapper::lockMediaServerList ();
703
+ if ( self )
704
+ msg_Err ( self->m_sd , " Unhandled event, please report ( type=%d )" , event_type );
705
+ UpnpInstanceWrapper::unlockMediaServerList ();
706
+ }
681
707
break ;
682
708
}
683
709
@@ -1322,9 +1348,25 @@ UpnpClient_Handle UpnpInstanceWrapper::handle() const
1322
1348
int UpnpInstanceWrapper::Callback (Upnp_EventType event_type, void *p_event, void *p_user_data)
1323
1349
{
1324
1350
VLC_UNUSED (p_user_data);
1325
- vlc_mutex_locker lock ( &s_lock );
1351
+ vlc_mutex_lock ( &s_lock );
1326
1352
if ( !UpnpInstanceWrapper::p_server_list )
1353
+ {
1354
+ vlc_mutex_unlock ( &s_lock );
1355
+ /* no MediaServerList available (anymore), do nothing */
1327
1356
return 0 ;
1328
- SD::MediaServerList::Callback ( event_type, p_event, UpnpInstanceWrapper::p_server_list );
1357
+ }
1358
+ vlc_mutex_unlock ( &s_lock );
1359
+ SD::MediaServerList::Callback ( event_type, p_event );
1329
1360
return 0 ;
1330
1361
}
1362
+
1363
+ SD::MediaServerList *UpnpInstanceWrapper::lockMediaServerList ()
1364
+ {
1365
+ vlc_mutex_lock ( &s_lock ); /* do not allow deleting the p_server_list while using it */
1366
+ return UpnpInstanceWrapper::p_server_list;
1367
+ }
1368
+
1369
+ void UpnpInstanceWrapper::unlockMediaServerList ()
1370
+ {
1371
+ vlc_mutex_unlock ( &s_lock );
1372
+ }
0 commit comments