SF Bug Tracker [ 1825278 ] AdvertiseAndReply sleeps with handle lock out

Applied patch from Alex (afaucher) to change some write locks to read
locks.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@237 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez 2007-11-08 01:54:50 +00:00
parent c9463545a8
commit 13a1fff7a1
5 changed files with 59 additions and 55 deletions

View File

@ -2,6 +2,11 @@
Version 1.6.1 Version 1.6.1
******************************************************************************* *******************************************************************************
2007-11-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1825278 ] AdvertiseAndReply sleeps with handle lock out
Applied patch from Alex (afaucher) to change some write locks to read
locks.
2007-11-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2007-11-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Adjusting libtool library numbers to reflect the last changes. * Adjusting libtool library numbers to reflect the last changes.

View File

@ -1570,7 +1570,7 @@ UpnpSearchAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSearchAsync \n" ); "Inside UpnpSearchAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -1746,7 +1746,7 @@ UpnpSubscribeAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSubscribeAsync \n" ); "Inside UpnpSubscribeAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -1763,15 +1763,13 @@ UpnpSubscribeAsync( IN UpnpClient_Handle Hnd,
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
} }
HandleUnlock();
Param = Param = (struct UpnpNonblockParam *)
( struct UpnpNonblockParam * ) malloc(sizeof (struct UpnpNonblockParam));
malloc( sizeof( struct UpnpNonblockParam ) );
if( Param == NULL ) { if( Param == NULL ) {
HandleUnlock();
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
HandleUnlock();
Param->FunName = SUBSCRIBE; Param->FunName = SUBSCRIBE;
Param->Handle = Hnd; Param->Handle = Hnd;
@ -1831,7 +1829,7 @@ UpnpSubscribe( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSubscribe \n" ); "Inside UpnpSubscribe \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -1891,7 +1889,7 @@ UpnpUnSubscribe( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpUnSubscribe \n" ); "Inside UpnpUnSubscribe \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -1950,7 +1948,7 @@ UpnpUnSubscribeAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpUnSubscribeAsync \n" ); "Inside UpnpUnSubscribeAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2024,7 +2022,7 @@ UpnpRenewSubscription( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRenewSubscription \n" ); "Inside UpnpRenewSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2089,7 +2087,7 @@ UpnpRenewSubscriptionAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRenewSubscriptionAsync \n" ); "Inside UpnpRenewSubscriptionAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2184,7 +2182,7 @@ UpnpNotify( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpNotify \n" ); "Inside UpnpNotify \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2255,7 +2253,7 @@ UpnpNotifyExt( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpNotify \n" ); "Inside UpnpNotify \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2332,7 +2330,7 @@ UpnpAcceptSubscription( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpAcceptSubscription \n" ); "Inside UpnpAcceptSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2408,7 +2406,7 @@ UpnpAcceptSubscriptionExt( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpAcceptSubscription \n" ); "Inside UpnpAcceptSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2504,7 +2502,7 @@ UpnpSendAction( IN UpnpClient_Handle Hnd,
} }
DevUDN_const = NULL; DevUDN_const = NULL;
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2588,7 +2586,7 @@ UpnpSendActionEx( IN UpnpClient_Handle Hnd,
return retVal; return retVal;
} }
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2664,7 +2662,7 @@ UpnpSendActionAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSendActionAsync \n" ); "Inside UpnpSendActionAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2784,7 +2782,7 @@ UpnpSendActionExAsync( IN UpnpClient_Handle Hnd,
return retVal; return retVal;
} }
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2898,7 +2896,7 @@ UpnpGetServiceVarStatusAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpGetServiceVarStatusAsync \n" ); "Inside UpnpGetServiceVarStatusAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@ -2978,7 +2976,7 @@ UpnpGetServiceVarStatus( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpGetServiceVarStatus \n" ); "Inside UpnpGetServiceVarStatus \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;

View File

@ -45,12 +45,12 @@
extern ithread_mutex_t GlobalClientSubscribeMutex; extern ithread_mutex_t GlobalClientSubscribeMutex;
/************************************************************************ /************************************************************************
* Function : GenaAutoRenewSubscription * Function : GenaAutoRenewSubscription
* *
* Parameters: * Parameters:
* IN void *input: Thread data(upnp_timeout *) needed to send the renewal * IN void *input: Thread data(upnp_timeout *) needed to send the renewal
* *
* Description: * Description:
* This is a thread function to send the renewal just before the * This is a thread function to send the renewal just before the
* subscription times out. * subscription times out.
* *
@ -93,7 +93,7 @@ GenaAutoRenewSubscription( IN void *input )
} }
} }
if( send_callback ) { if( send_callback ) {
HandleLock(); HandleReadLock();
if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) { if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
free_upnp_timeout( event ); free_upnp_timeout( event );
@ -113,14 +113,14 @@ GenaAutoRenewSubscription( IN void *input )
} }
/************************************************************************ /************************************************************************
* Function : ScheduleGenaAutoRenew * Function : ScheduleGenaAutoRenew
* *
* Parameters: * Parameters:
* IN int client_handle: Handle that also contains the subscription list * IN int client_handle: Handle that also contains the subscription list
* IN int TimeOut: The time out value of the subscription * IN int TimeOut: The time out value of the subscription
* IN client_subscription * sub: Subscription being renewed * IN client_subscription * sub: Subscription being renewed
* *
* Description: * Description:
* This function schedules a job to renew the subscription just before * This function schedules a job to renew the subscription just before
* time out. * time out.
* *
@ -188,14 +188,14 @@ ScheduleGenaAutoRenew( IN int client_handle,
} }
/************************************************************************ /************************************************************************
* Function : gena_unsubscribe * Function : gena_unsubscribe
* *
* Parameters: * Parameters:
* IN char *url: Event URL of the service * IN char *url: Event URL of the service
* IN char *sid: The subcription ID. * IN char *sid: The subcription ID.
* OUT http_parser_t* response: The UNSUBCRIBE response from the device * OUT http_parser_t* response: The UNSUBCRIBE response from the device
* *
* Description: * Description:
* This function sends the UNSUBCRIBE gena request and recieves the * This function sends the UNSUBCRIBE gena request and recieves the
* response from the device and returns it as a parameter * response from the device and returns it as a parameter
* *
@ -251,9 +251,9 @@ gena_unsubscribe( IN char *url,
} }
/************************************************************************ /************************************************************************
* Function : gena_subscribe * Function : gena_subscribe
* *
* Parameters: * Parameters:
* IN char *url: url of service to subscribe * IN char *url: url of service to subscribe
* INOUT int* timeout:subscription time desired (in secs) * INOUT int* timeout:subscription time desired (in secs)
* IN char* renewal_sid:for renewal, this contains a currently h * IN char* renewal_sid:for renewal, this contains a currently h
@ -261,7 +261,7 @@ gena_unsubscribe( IN char *url,
* subscription, this must be NULL * subscription, this must be NULL
* OUT char** sid: SID returned by the subscription or renew msg * OUT char** sid: SID returned by the subscription or renew msg
* *
* Description: * Description:
* This function subscribes or renew subscription * This function subscribes or renew subscription
* *
* Returns: int * Returns: int
@ -374,13 +374,13 @@ gena_subscribe( IN char *url,
} }
/************************************************************************ /************************************************************************
* Function : genaUnregisterClient * Function : genaUnregisterClient
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: Handle containing all the control * IN UpnpClient_Handle client_handle: Handle containing all the control
* point related information * point related information
* *
* Description: * Description:
* This function unsubcribes all the outstanding subscriptions and cleans * This function unsubcribes all the outstanding subscriptions and cleans
* the subscription list. This function is called when control point * the subscription list. This function is called when control point
* unregisters. * unregisters.
@ -435,12 +435,12 @@ genaUnregisterClient( IN UpnpClient_Handle client_handle )
/************************************************************************ /************************************************************************
* Function : genaUnSubscribe * Function : genaUnSubscribe
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: UPnP client handle * IN UpnpClient_Handle client_handle: UPnP client handle
* IN SID in_sid: The subscription ID * IN SID in_sid: The subscription ID
* *
* Description: * Description:
* This function unsubscribes a SID. It first validates the SID and * This function unsubscribes a SID. It first validates the SID and
* client_handle,copies the subscription, sends UNSUBSCRIBE http request * client_handle,copies the subscription, sends UNSUBSCRIBE http request
* to service processes request and finally removes the subscription * to service processes request and finally removes the subscription
@ -506,8 +506,8 @@ genaUnSubscribe( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : genaSubscribe * Function : genaSubscribe
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: * IN UpnpClient_Handle client_handle:
* IN char * PublisherURL: NULL Terminated, of the form : * IN char * PublisherURL: NULL Terminated, of the form :
* "http://134.134.156.80:4000/RedBulb/Event" * "http://134.134.156.80:4000/RedBulb/Event"
@ -516,7 +516,7 @@ genaUnSubscribe( IN UpnpClient_Handle client_handle,
* by Service, -1 for infinite * by Service, -1 for infinite
* OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller * OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller
* *
* Description: * Description:
* This function subscribes to a PublisherURL ( also mentioned as EventURL * This function subscribes to a PublisherURL ( also mentioned as EventURL
* some places). It sends SUBSCRIBE http request to service processes * some places). It sends SUBSCRIBE http request to service processes
* request. Finally adds a Subscription to * request. Finally adds a Subscription to
@ -543,10 +543,10 @@ genaSubscribe( IN UpnpClient_Handle client_handle,
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUBSCRIBE BEGIN" ); "GENA SUBSCRIBE BEGIN" );
HandleLock();
memset( out_sid, 0, sizeof( Upnp_SID ) ); memset( out_sid, 0, sizeof( Upnp_SID ) );
HandleReadLock();
// validate handle // validate handle
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) { if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
@ -616,15 +616,15 @@ genaSubscribe( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : genaRenewSubscription * Function : genaRenewSubscription
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: Client handle * IN UpnpClient_Handle client_handle: Client handle
* IN const Upnp_SID in_sid: subscription ID * IN const Upnp_SID in_sid: subscription ID
* INOUT int * TimeOut: requested Duration, if -1, then "infinite". * INOUT int * TimeOut: requested Duration, if -1, then "infinite".
* in the OUT case: actual Duration granted * in the OUT case: actual Duration granted
* by Service, -1 for infinite * by Service, -1 for infinite
* *
* Description: * Description:
* This function renews a SID. It first validates the SID and * This function renews a SID. It first validates the SID and
* client_handle and copies the subscription. It sends RENEW * client_handle and copies the subscription. It sends RENEW
* (modified SUBSCRIBE) http request to service and processes * (modified SUBSCRIBE) http request to service and processes
@ -724,14 +724,14 @@ genaRenewSubscription( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : gena_process_notification_event * Function : gena_process_notification_event
* *
* Parameters: * Parameters:
* IN SOCKINFO *info: Socket structure containing the device socket * IN SOCKINFO *info: Socket structure containing the device socket
* information * information
* IN http_message_t* event: The http message contains the GENA * IN http_message_t* event: The http message contains the GENA
* notification * notification
* *
* Description: * Description:
* This function processes NOTIFY events that are sent by devices. * This function processes NOTIFY events that are sent by devices.
* called by genacallback() * called by genacallback()
* *
@ -881,3 +881,4 @@ gena_process_notification_event( IN SOCKINFO * info,
#endif // INCLUDE_CLIENT_APIS #endif // INCLUDE_CLIENT_APIS
#endif // EXCLUDE_GENA #endif // EXCLUDE_GENA

View File

@ -365,7 +365,7 @@ genaNotifyThread( IN void *input )
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
ThreadPoolJob job; ThreadPoolJob job;
HandleLock(); HandleReadLock();
//validate context //validate context
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) { if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {

View File

@ -125,7 +125,7 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
// we are assuming that there can be only one client supported at a time // we are assuming that there can be only one client supported at a time
HandleLock(); HandleReadLock();
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();