From f87dbf8115b41573d880177b7bf04d24d596c68a Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Tue, 6 Nov 2007 02:29:03 +0000 Subject: [PATCH] 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. git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@233 119443c7-1b9e-41f8-b6fc-b9c35fce742c --- ChangeLog | 7 +++++++ THANKS | 3 ++- upnp/src/api/upnpapi.c | 20 ++++++++++---------- upnp/src/inc/upnpapi.h | 21 ++++++++++++++------- upnp/src/ssdp/ssdp_server.c | 7 ++----- 5 files changed, 35 insertions(+), 23 deletions(-) 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