diff --git a/ChangeLog b/ChangeLog index f1dcabf..49952c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,17 @@ 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 6c7bd90..cbd7aea 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -1980,7 +1980,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"); @@ -2166,7 +2168,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"); @@ -2292,7 +2296,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"); @@ -2764,7 +2770,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"); @@ -2884,7 +2892,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"); @@ -2951,7 +2961,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 136a3ca..3dc55ed 100644 --- a/upnp/src/ssdp/ssdp_ctrlpt.c +++ b/upnp/src/ssdp/ssdp_ctrlpt.c @@ -291,8 +291,9 @@ void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr_storage *dest_ TPJobSetFreeFunction(&job, (free_routine) free); - ThreadPoolAdd(&gRecvThreadPool, &job, - NULL); + if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0) { + free(threadData); + } } } node = ListNext(&ctrlpt_info->SsdpSearchList, node);