diff --git a/ChangeLog b/ChangeLog index b7e578e..e00c89f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -357,6 +357,17 @@ Version 1.8.0 Version 1.6.19 ******************************************************************************* +2013-09-10 zexian chen + + Hi, + + I had found some bugs about memory leak on libupnp-1.6.18. + + It may lead to memory leak when calling ThreadPoolAdd() or + ThreadPoolAddPersistent() which does not return 0. + + See the attachment for patch. + 2013-09-03 Peng Fix return value of config_description_doc. diff --git a/THANKS b/THANKS index e35467d..1ea8e36 100644 --- a/THANKS +++ b/THANKS @@ -71,5 +71,6 @@ exempt of errors. - Tom (tomdev2) - Yoichi Nakayama (yoichi) - zephyrus (zephyrus00jp) +- zexian chen - Zheng Peng (darkelf2010) diff --git a/threadutil/src/TimerThread.c b/threadutil/src/TimerThread.c index cbbc3c8..85e2d8e 100644 --- a/threadutil/src/TimerThread.c +++ b/threadutil/src/TimerThread.c @@ -96,10 +96,17 @@ static void *TimerThreadWorker( /* If time has elapsed, schedule job. */ if (nextEvent && currentTime >= nextEventTime) { if( nextEvent->persistent ) { - ThreadPoolAddPersistent( timer->tp, &nextEvent->job, - &tempId ); + if (ThreadPoolAddPersistent( timer->tp, &nextEvent->job, &tempId ) != 0) { + if (nextEvent->job.arg != NULL && nextEvent->job.free_func != NULL) { + nextEvent->job.free_func(nextEvent->job.arg); + } + } } else { - ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId ); + if (ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId ) != 0) { + if (nextEvent->job.arg != NULL && nextEvent->job.free_func != NULL) { + nextEvent->job.free_func(nextEvent->job.arg); + } + } } ListDelNode( &timer->eventQ, head, 0 ); FreeTimerEvent( timer, nextEvent ); diff --git a/upnp/src/api/upnpapi.c b/upnp/src/api/upnpapi.c index ccf7bc5..ff1ddc2 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -2013,7 +2013,9 @@ int UpnpSubscribeAsync( TPJobInit(&job, (start_routine)UpnpThreadDistribution, Param); TPJobSetFreeFunction(&job, (free_routine)free); TPJobSetPriority(&job, MED_PRIORITY); - ThreadPoolAdd(&gSendThreadPool, &job, NULL); + if (ThreadPoolAdd(&gSendThreadPool, &job, NULL) != 0) { + free(Param); + } UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpSubscribeAsync\n"); @@ -2199,7 +2201,9 @@ int UpnpUnSubscribeAsync( TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param ); TPJobSetFreeFunction( &job, ( free_routine ) free ); TPJobSetPriority( &job, MED_PRIORITY ); - ThreadPoolAdd( &gSendThreadPool, &job, NULL ); + if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) { + free(Param); + } exit_function: UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpUnSubscribeAsync\n"); @@ -2325,7 +2329,9 @@ int UpnpRenewSubscriptionAsync( TPJobInit( &job, ( start_routine ) UpnpThreadDistribution, Param ); TPJobSetFreeFunction( &job, ( free_routine ) free ); TPJobSetPriority( &job, MED_PRIORITY ); - ThreadPoolAdd( &gSendThreadPool, &job, NULL ); + if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) { + free(Param); + } UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpRenewSubscriptionAsync\n"); @@ -2797,7 +2803,9 @@ int UpnpSendActionAsync( TPJobSetFreeFunction( &job, ( free_routine ) free ); TPJobSetPriority( &job, MED_PRIORITY ); - ThreadPoolAdd( &gSendThreadPool, &job, NULL ); + if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) { + free(Param); + } UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpSendActionAsync \n"); @@ -2917,7 +2925,9 @@ int UpnpSendActionExAsync( TPJobSetFreeFunction( &job, ( free_routine ) free ); TPJobSetPriority( &job, MED_PRIORITY ); - ThreadPoolAdd( &gSendThreadPool, &job, NULL ); + if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) { + free(Param); + } UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpSendActionAsync\n"); @@ -2984,7 +2994,9 @@ int UpnpGetServiceVarStatusAsync( TPJobSetPriority( &job, MED_PRIORITY ); - ThreadPoolAdd( &gSendThreadPool, &job, NULL ); + if (ThreadPoolAdd( &gSendThreadPool, &job, NULL ) != 0) { + free(Param); + } UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Exiting UpnpGetServiceVarStatusAsync\n"); diff --git a/upnp/src/genlib/miniserver/miniserver.c b/upnp/src/genlib/miniserver/miniserver.c index eae6eca..3361bd1 100644 --- a/upnp/src/genlib/miniserver/miniserver.c +++ b/upnp/src/genlib/miniserver/miniserver.c @@ -910,6 +910,7 @@ int StartMiniServer( sock_close(miniSocket->ssdpReqSock4); sock_close(miniSocket->ssdpReqSock6); #endif /* INCLUDE_CLIENT_APIS */ + free(miniSocket); return UPNP_E_OUTOF_MEMORY; } /* Wait for miniserver to start. */ diff --git a/upnp/src/ssdp/ssdp_ctrlpt.c b/upnp/src/ssdp/ssdp_ctrlpt.c index c82a320..37b67ab 100644 --- a/upnp/src/ssdp/ssdp_ctrlpt.c +++ b/upnp/src/ssdp/ssdp_ctrlpt.c @@ -295,9 +295,10 @@ void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr_storage *dest_ TPJobSetPriority(&job, MED_PRIORITY); TPJobSetFreeFunction(&job, (free_routine) - SSDPResultData_delete); - ThreadPoolAdd(&gRecvThreadPool, &job, - NULL); + free); + if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0) { + SSDPResultData_delete(threadData); + } } } node = ListNext(&ctrlpt_info->SsdpSearchList, node);