diff --git a/ChangeLog b/ChangeLog index be4c899..d40ce1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,13 @@ Version 1.6.1 ******************************************************************************* +2007-11-06 Marcelo Jimenez + * GlobalHndMutex, which was a mutex is now GlobalHndRWLock, which is a + rwlock. HandleLock() is mapped to HandleWriteLock() while all other + instances have not been checked. One instance in AdvertiseAndReply() + has been changed to HandleReadLock(). Thanks to Alex (afaucher) for the + bug report and suggestions. + 2007-11-06 Marcelo Jimenez * Added support for rwlocks. diff --git a/THANKS b/THANKS index 72559a5..18c97d3 100644 --- a/THANKS +++ b/THANKS @@ -6,6 +6,7 @@ suggesting various improvements or submitting actual code. Here is a list of these people. Help us keep it complete and exempt of errors. +- Alex (afaucher) - Arno Willig - Bob Ciora - Chaos @@ -24,7 +25,7 @@ exempt of errors. - Leuk_He - Loigu - Luke Kim -- Marcelo Roberto Jimenez +- Marcelo Roberto Jimenez (mroberto) - Markus Strobl - Nektarios K. Papadopoulos - Oskar Liljeblad diff --git a/upnp/src/api/upnpapi.c b/upnp/src/api/upnpapi.c index faa742a..9cda81d 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -84,8 +84,8 @@ virtualDirList *pVirtualDirList; // Mutex to synchronize the subscription handling at the client side CLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex; ) -//Mutex to synchronize handles ( root device or control point handle) - ithread_mutex_t GlobalHndMutex; +// rwlock to synchronize handles (root device or control point handle) + ithread_rwlock_t GlobalHndRWLock; // Mutex to synchronize the uuid creation process ithread_mutex_t gUUIDMutex; @@ -213,26 +213,26 @@ int UpnpInit( IN const char *HostIP, #ifdef __CYGWIN__ /* On Cygwin, pthread_mutex_init() fails without this memset. */ /* TODO: Fix Cygwin so we don't need this memset(). */ - memset(&GlobalHndMutex, 0, sizeof(GlobalHndMutex)); + memset(&GlobalHndRWLock, 0, sizeof(GlobalHndRWLock)); #endif - if( ithread_mutex_init( &GlobalHndMutex, NULL ) != 0 ) { + if (ithread_rwlock_init(&GlobalHndRWLock, NULL) != 0) { return UPNP_E_INIT_FAILED; } - if( ithread_mutex_init( &gUUIDMutex, NULL ) != 0 ) { + if (ithread_mutex_init(&gUUIDMutex, NULL) != 0) { return UPNP_E_INIT_FAILED; } // initialize subscribe mutex #ifdef INCLUDE_CLIENT_APIS - if ( ithread_mutex_init( &GlobalClientSubscribeMutex, NULL ) != 0 ) { + if (ithread_mutex_init(&GlobalClientSubscribeMutex, NULL) != 0) { return UPNP_E_INIT_FAILED; } #endif - HandleLock(); - if( HostIP != NULL ) + HandleLock(); + if( HostIP != NULL ) { strcpy( LOCAL_HOST, HostIP ); - else { + } else { if( getlocalhostname( LOCAL_HOST ) != UPNP_E_SUCCESS ) { HandleUnlock(); return UPNP_E_INIT_FAILED; @@ -447,7 +447,7 @@ UpnpFinish() #ifdef INCLUDE_CLIENT_APIS ithread_mutex_destroy(&GlobalClientSubscribeMutex); #endif - ithread_mutex_destroy(&GlobalHndMutex); + ithread_rwlock_destroy(&GlobalHndRWLock); ithread_mutex_destroy(&gUUIDMutex); // remove all virtual dirs diff --git a/upnp/src/inc/upnpapi.h b/upnp/src/inc/upnpapi.h index 5f6a58c..d2a23a6 100644 --- a/upnp/src/inc/upnpapi.h +++ b/upnp/src/inc/upnpapi.h @@ -98,18 +98,25 @@ struct Handle_Info int aliasInstalled; // 0 = not installed; otherwise installed }; -extern ithread_mutex_t GlobalHndMutex; +extern ithread_rwlock_t GlobalHndRWLock; Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo); -#define HandleLock() \ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying Lock"); \ - ithread_mutex_lock(&GlobalHndMutex); \ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "LOCK"); +#define HandleLock() HandleWriteLock() + +#define HandleWriteLock() \ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a write lock"); \ + ithread_rwlock_wrlock(&GlobalHndRWLock); \ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Write lock acquired"); + +#define HandleReadLock() \ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a read lock"); \ + ithread_rwlock_rdlock(&GlobalHndRWLock); \ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Read lock acquired"); #define HandleUnlock() \ UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \ - ithread_mutex_unlock(&GlobalHndMutex); \ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlock"); + ithread_rwlock_unlock(&GlobalHndRWLock); \ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlocked rwlock"); Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out, struct Handle_Info **HndInfo); diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index 1713dd9..bc2300f 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -122,16 +122,13 @@ int AdvertiseAndReply( IN int AdFlag, "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag ); - HandleLock(); + // Use a read lock + HandleReadLock(); if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { HandleUnlock(); return UPNP_E_INVALID_HANDLE; } defaultExp = SInfo->MaxAge; - - //Modifed to prevent more than one thread from accessing the - //UpnpDocument stored with the handle at the same time - // HandleUnlock(); nodeList = NULL; //get server info