[vlc-commits] upnp: search in a separate thread
Thomas Guillem
git at videolan.org
Mon Feb 8 16:02:56 CET 2016
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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 );
}
More information about the vlc-commits
mailing list