vlc | branch: master | Thomas Guillem <[email protected]> | Mon Feb 8 14:51:41 2016 +0100| [ccd6ba5de29ecee6169472beb6240dfe0ddecdc3] | committer: Thomas Guillem
upnp: search in a separate thread pf_open from service_discovery shouldn't block but UpnpSearchAsync can take more than one seconds. Indeed, contrary to what the libupnp doc states, UpnpSearchAsync is blocking (select() and send() are called). This is not a perfect solution. Indeed if pf_close is called just after pf_open, it will also block. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ccd6ba5de29ecee6169472beb6240dfe0ddecdc3 --- modules/services_discovery/upnp.cpp | 55 +++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/modules/services_discovery/upnp.cpp b/modules/services_discovery/upnp.cpp index 9062e0e..0aaed99 100644 --- a/modules/services_discovery/upnp.cpp +++ b/modules/services_discovery/upnp.cpp @@ -63,6 +63,7 @@ struct services_discovery_sys_t { UpnpInstanceWrapper* p_upnp; SD::MediaServerList* p_server_list; + vlc_thread_t thread; }; struct access_sys_t @@ -198,6 +199,29 @@ IXML_Document* parseBrowseResult( IXML_Document* p_doc ) namespace SD { +static void * +SearchThread( void *p_data ) +{ + services_discovery_t *p_sd = ( services_discovery_t* )p_data; + services_discovery_sys_t *p_sys = p_sd->p_sys; + + /* Search for media servers */ + int i_res = UpnpSearchAsync( p_sys->p_upnp->handle(), 5, + MEDIA_SERVER_DEVICE_TYPE, p_sys->p_upnp ); + if( i_res != UPNP_E_SUCCESS ) + { + msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) ); + return NULL; + } + + /* Search for Sat Ip servers*/ + i_res = UpnpSearchAsync( p_sys->p_upnp->handle(), 5, + SATIP_SERVER_DEVICE_TYPE, p_sys->p_upnp ); + if( i_res != UPNP_E_SUCCESS ) + msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) ); + return NULL; +} + /* * Initializes UPNP instance. */ @@ -220,27 +244,20 @@ static int Open( vlc_object_t *p_this ) p_sys->p_upnp = UpnpInstanceWrapper::get( p_this, SD::MediaServerList::Callback, p_sys->p_server_list ); if ( !p_sys->p_upnp ) { - Close( p_this ); - return VLC_EGENERIC; - } - - /* Search for media servers */ - int i_res = UpnpSearchAsync( p_sys->p_upnp->handle(), 5, - MEDIA_SERVER_DEVICE_TYPE, p_sys->p_upnp ); - if( i_res != UPNP_E_SUCCESS ) - { - msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) ); - Close( p_this ); + delete p_sys->p_server_list; + free(p_sys); return VLC_EGENERIC; } - /* Search for Sat Ip servers*/ - i_res = UpnpSearchAsync( p_sys->p_upnp->handle(), 5, - SATIP_SERVER_DEVICE_TYPE, p_sys->p_upnp ); - if( i_res != UPNP_E_SUCCESS ) + /* XXX: Contrary to what the libupnp doc states, UpnpSearchAsync is + * blocking (select() and send() are called). Therefore, Call + * UpnpSearchAsync from an other thread. */ + if ( vlc_clone( &p_sys->thread, SearchThread, p_this, + VLC_THREAD_PRIORITY_LOW ) ) { - msg_Err( p_sd, "Error sending search request: %s", UpnpGetErrorMessage( i_res ) ); - Close( p_this ); + p_sys->p_upnp->release( true ); + delete p_sys->p_server_list; + free(p_sys); return VLC_EGENERIC; } @@ -255,8 +272,8 @@ static void Close( vlc_object_t *p_this ) services_discovery_t *p_sd = ( services_discovery_t* )p_this; services_discovery_sys_t *p_sys = p_sd->p_sys; - if (p_sys->p_upnp) - p_sys->p_upnp->release( true ); + vlc_join( p_sys->thread, NULL ); + p_sys->p_upnp->release( true ); delete p_sys->p_server_list; free( p_sys ); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
