workaround added for applications that don't catch SIGEPIPE
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.4.x@75 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
6
README
6
README
@@ -272,6 +272,12 @@ Rename Pre-build.2 to pthreads.
|
|||||||
Open the provided workspace build\libupnp.dsw with Visual C++ 6.0 and select
|
Open the provided workspace build\libupnp.dsw with Visual C++ 6.0 and select
|
||||||
Build->Build libupnp.dll (F7)
|
Build->Build libupnp.dll (F7)
|
||||||
|
|
||||||
|
For building a static library instead of a DLL and for using the static
|
||||||
|
pthreads-w32 library following switches need to be defined additionally:
|
||||||
|
|
||||||
|
UPNP_STATIC_LIB - for creating a statically linkable UPnP-library
|
||||||
|
PTW32_STATIC_LIB - for using the static pthreads32 library
|
||||||
|
|
||||||
|
|
||||||
5) Install/Uninstall Instructions
|
5) Install/Uninstall Instructions
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
@@ -38,11 +38,15 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifdef LIBUPNP_EXPORTS
|
#ifndef UPNP_STATIC_LIB
|
||||||
// set up declspec for dll export to make functions visible to library users
|
#ifdef LIBUPNP_EXPORTS
|
||||||
#define EXPORT_SPEC __declspec(dllexport)
|
// set up declspec for dll export to make functions visible to library users
|
||||||
|
#define EXPORT_SPEC __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define EXPORT_SPEC __declspec(dllimport)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC __declspec(dllimport)
|
#define EXPORT_SPEC
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC
|
#define EXPORT_SPEC
|
||||||
|
@@ -527,11 +527,15 @@ extern "C" {
|
|||||||
#define imillisleep(x) usleep(1000*x)
|
#define imillisleep(x) usleep(1000*x)
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifdef LIBUPNP_EXPORTS
|
#ifndef UPNP_STATIC_LIB
|
||||||
// set up declspec for dll export to make functions visible to library users
|
#ifdef LIBUPNP_EXPORTS
|
||||||
#define EXPORT_SPEC __declspec(dllexport)
|
// set up declspec for dll export to make functions visible to library users
|
||||||
|
#define EXPORT_SPEC __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define EXPORT_SPEC __declspec(dllimport)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC __declspec(dllimport)
|
#define EXPORT_SPEC
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC
|
#define EXPORT_SPEC
|
||||||
|
@@ -289,7 +289,8 @@ SetRelTimeout( struct timespec *time,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
* ThreadPoolStats *stats must be valid non null stats structure
|
* ThreadPoolStats *stats must be valid non null stats structure
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
STATSONLY( static void StatsInit( ThreadPoolStats * stats ) {
|
#ifdef STATS
|
||||||
|
static void StatsInit( ThreadPoolStats * stats ) {
|
||||||
assert( stats != NULL ); stats->totalIdleTime = 0; stats->totalJobsHQ = 0; stats->totalJobsLQ = 0; stats->totalJobsMQ = 0; stats->totalTimeHQ = 0; stats->totalTimeMQ = 0; stats->totalTimeLQ = 0; stats->totalWorkTime = 0; stats->totalIdleTime = 0; stats->avgWaitHQ = 0; //average wait in HQ
|
assert( stats != NULL ); stats->totalIdleTime = 0; stats->totalJobsHQ = 0; stats->totalJobsLQ = 0; stats->totalJobsMQ = 0; stats->totalTimeHQ = 0; stats->totalTimeMQ = 0; stats->totalTimeLQ = 0; stats->totalWorkTime = 0; stats->totalIdleTime = 0; stats->avgWaitHQ = 0; //average wait in HQ
|
||||||
stats->avgWaitMQ = 0; //average wait in MQ
|
stats->avgWaitMQ = 0; //average wait in MQ
|
||||||
stats->avgWaitLQ = 0;
|
stats->avgWaitLQ = 0;
|
||||||
@@ -297,7 +298,7 @@ STATSONLY( static void StatsInit( ThreadPoolStats * stats ) {
|
|||||||
stats->idleThreads = 0;
|
stats->idleThreads = 0;
|
||||||
stats->persistentThreads = 0;
|
stats->persistentThreads = 0;
|
||||||
stats->maxThreads = 0; stats->totalThreads = 0;}
|
stats->maxThreads = 0; stats->totalThreads = 0;}
|
||||||
)
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: CalcWaitTime
|
* Function: CalcWaitTime
|
||||||
@@ -313,7 +314,8 @@ STATSONLY( static void StatsInit( ThreadPoolStats * stats ) {
|
|||||||
* ThreadPriority p
|
* ThreadPriority p
|
||||||
* ThreadPoolJob *job
|
* ThreadPoolJob *job
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
STATSONLY( static void CalcWaitTime( ThreadPool * tp,
|
#ifdef STATS
|
||||||
|
static void CalcWaitTime( ThreadPool * tp,
|
||||||
ThreadPriority p,
|
ThreadPriority p,
|
||||||
ThreadPoolJob * job ) {
|
ThreadPoolJob * job ) {
|
||||||
struct timeb now;
|
struct timeb now;
|
||||||
@@ -329,7 +331,7 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
assert( 0 );}
|
assert( 0 );}
|
||||||
}
|
}
|
||||||
|
|
||||||
)
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: SetSeed
|
* Function: SetSeed
|
||||||
@@ -380,6 +382,12 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
int retCode = 0;
|
int retCode = 0;
|
||||||
int persistent = -1;
|
int persistent = -1;
|
||||||
ThreadPool *tp = ( ThreadPool * ) arg;
|
ThreadPool *tp = ( ThreadPool * ) arg;
|
||||||
|
//leuk_he allow static linking
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
pthread_win32_thread_attach_np();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
assert( tp != NULL );
|
assert( tp != NULL );
|
||||||
|
|
||||||
@@ -447,7 +455,12 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
tp->totalThreads--;
|
tp->totalThreads--;
|
||||||
ithread_cond_broadcast( &tp->start_and_shutdown );
|
ithread_cond_broadcast( &tp->start_and_shutdown );
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ithread_mutex_unlock( &tp->mutex );
|
||||||
|
//leuk_he
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
pthread_win32_thread_detach_np ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,6 +489,12 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
ithread_cond_broadcast( &tp->start_and_shutdown );
|
ithread_cond_broadcast( &tp->start_and_shutdown );
|
||||||
|
|
||||||
ithread_mutex_unlock( &tp->mutex );
|
ithread_mutex_unlock( &tp->mutex );
|
||||||
|
//leuk_he
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
pthread_win32_thread_detach_np ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
@@ -703,6 +722,12 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
if( tp == NULL ) {
|
if( tp == NULL ) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
//leuk_he
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
pthread_win32_process_attach_np();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
retCode += ithread_mutex_init( &tp->mutex, NULL );
|
retCode += ithread_mutex_init( &tp->mutex, NULL );
|
||||||
assert( retCode == 0 );
|
assert( retCode == 0 );
|
||||||
@@ -1461,7 +1486,8 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATSONLY( void ThreadPoolPrintStats( ThreadPoolStats * stats ) {
|
#ifdef STATS
|
||||||
|
void ThreadPoolPrintStats( ThreadPoolStats * stats ) {
|
||||||
assert( stats != NULL ); if( stats == NULL ) {
|
assert( stats != NULL ); if( stats == NULL ) {
|
||||||
return;}
|
return;}
|
||||||
|
|
||||||
@@ -1471,13 +1497,13 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
printf( "ThreadPoolStats at Time: %ld\n", time( NULL ) );
|
printf( "ThreadPoolStats at Time: %ld\n", time( NULL ) );
|
||||||
#endif
|
#endif
|
||||||
printf
|
printf
|
||||||
( "Average Wait in High Priority Q in milliseconds: %lf\n",
|
( "Average Wait in High Priority Q in milliseconds: %f\n",
|
||||||
stats->avgWaitHQ );
|
stats->avgWaitHQ );
|
||||||
printf
|
printf
|
||||||
( "Average Wait in Med Priority Q in milliseconds: %lf\n",
|
( "Average Wait in Med Priority Q in milliseconds: %f\n",
|
||||||
stats->avgWaitMQ );
|
stats->avgWaitMQ );
|
||||||
printf
|
printf
|
||||||
( "Averate Wait in Low Priority Q in milliseconds: %lf\n",
|
( "Averate Wait in Low Priority Q in milliseconds: %f\n",
|
||||||
stats->avgWaitLQ );
|
stats->avgWaitLQ );
|
||||||
printf( "Max Threads Active: %d\n", stats->maxThreads );
|
printf( "Max Threads Active: %d\n", stats->maxThreads );
|
||||||
printf( "Current Worker Threads: %d\n",
|
printf( "Current Worker Threads: %d\n",
|
||||||
@@ -1486,11 +1512,11 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
stats->persistentThreads );
|
stats->persistentThreads );
|
||||||
printf( "Current Idle Threads: %d\n", stats->idleThreads );
|
printf( "Current Idle Threads: %d\n", stats->idleThreads );
|
||||||
printf( "Total Threads : %d\n", stats->totalThreads );
|
printf( "Total Threads : %d\n", stats->totalThreads );
|
||||||
printf( "Total Time spent Working in seconds: %lf\n",
|
printf( "Total Time spent Working in seconds: %f\n",
|
||||||
stats->totalWorkTime );
|
stats->totalWorkTime );
|
||||||
printf( "Total Time spent Idle in seconds : %lf\n",
|
printf( "Total Time spent Idle in seconds : %f\n",
|
||||||
stats->totalIdleTime );}
|
stats->totalIdleTime );}
|
||||||
)
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ThreadPoolGetStats
|
* Function: ThreadPoolGetStats
|
||||||
@@ -1505,7 +1531,8 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Always returns 0.
|
* Always returns 0.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
STATSONLY( int
|
#ifdef STATS
|
||||||
|
int
|
||||||
ThreadPoolGetStats( ThreadPool * tp,
|
ThreadPoolGetStats( ThreadPool * tp,
|
||||||
ThreadPoolStats * stats ) {
|
ThreadPoolStats * stats ) {
|
||||||
|
|
||||||
@@ -1542,4 +1569,4 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default:
|
|||||||
|
|
||||||
return 0;}
|
return 0;}
|
||||||
|
|
||||||
)
|
#endif
|
||||||
|
@@ -47,11 +47,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifdef LIBUPNP_EXPORTS
|
#ifndef UPNP_STATIC_LIB
|
||||||
// set up declspec for dll export to make functions visible to library users
|
#ifdef LIBUPNP_EXPORTS
|
||||||
#define EXPORT_SPEC __declspec(dllexport)
|
// set up declspec for dll export to make functions visible to library users
|
||||||
|
#define EXPORT_SPEC __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define EXPORT_SPEC __declspec(dllimport)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC __declspec(dllimport)
|
#define EXPORT_SPEC
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define EXPORT_SPEC
|
#define EXPORT_SPEC
|
||||||
|
@@ -415,6 +415,13 @@ UpnpFinish( )
|
|||||||
|
|
||||||
// remove all virtual dirs
|
// remove all virtual dirs
|
||||||
UpnpRemoveAllVirtualDirs( );
|
UpnpRemoveAllVirtualDirs( );
|
||||||
|
//leuk_he allow static linking:
|
||||||
|
#ifdef WIN32
|
||||||
|
#ifdef PTW32_STATIC_LIB
|
||||||
|
pthread_win32_thread_detach_np ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
UpnpSdkInit = 0;
|
UpnpSdkInit = 0;
|
||||||
|
|
||||||
|
@@ -348,14 +348,9 @@ UpnpMakeAction( const char *ActionName,
|
|||||||
va_list ArgList;
|
va_list ArgList;
|
||||||
IXML_Document *out = NULL;
|
IXML_Document *out = NULL;
|
||||||
|
|
||||||
if( NumArg > 0 ) {
|
va_start( ArgList, Arg );
|
||||||
va_start( ArgList, Arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
out = makeAction( 0, ActionName, ServType, NumArg, Arg, ArgList );
|
out = makeAction( 0, ActionName, ServType, NumArg, Arg, ArgList );
|
||||||
if( NumArg > 0 ) {
|
va_end( ArgList );
|
||||||
va_end( ArgList );
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -390,14 +385,9 @@ UpnpMakeActionResponse( const char *ActionName,
|
|||||||
va_list ArgList;
|
va_list ArgList;
|
||||||
IXML_Document *out = NULL;
|
IXML_Document *out = NULL;
|
||||||
|
|
||||||
if( NumArg > 0 ) {
|
va_start( ArgList, Arg );
|
||||||
va_start( ArgList, Arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
out = makeAction( 1, ActionName, ServType, NumArg, Arg, ArgList );
|
out = makeAction( 1, ActionName, ServType, NumArg, Arg, ArgList );
|
||||||
if( NumArg > 0 ) {
|
va_end( ArgList );
|
||||||
va_end( ArgList );
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include "statcodes.h"
|
#include "statcodes.h"
|
||||||
#include "httpparser.h"
|
#include "httpparser.h"
|
||||||
#include "httpreadwrite.h"
|
#include "httpreadwrite.h"
|
||||||
|
#include "ssdplib.h"
|
||||||
|
|
||||||
#include "unixutil.h"
|
#include "unixutil.h"
|
||||||
|
|
||||||
@@ -755,8 +756,8 @@ genaInitNotifyExt( IN UpnpDevice_Handle device_handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
|
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
|
||||||
"%d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
|
"%ld\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
|
||||||
strlen( propertySet ) + 1 );
|
(long) strlen( propertySet ) + 1 );
|
||||||
|
|
||||||
//schedule thread for initial notification
|
//schedule thread for initial notification
|
||||||
|
|
||||||
@@ -892,8 +893,8 @@ genaNotifyAllExt( IN UpnpDevice_Handle device_handle,
|
|||||||
//changed to add null terminator at end of content
|
//changed to add null terminator at end of content
|
||||||
//content length = (length in bytes of property set) + null char
|
//content length = (length in bytes of property set) + null char
|
||||||
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
|
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
|
||||||
"%d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
|
"%ld\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
|
||||||
strlen( propertySet ) + 1 );
|
(long) strlen( propertySet ) + 1 );
|
||||||
|
|
||||||
HandleLock( );
|
HandleLock( );
|
||||||
|
|
||||||
@@ -1053,9 +1054,9 @@ genaNotifyAll( IN UpnpDevice_Handle device_handle,
|
|||||||
}
|
}
|
||||||
//changed to add null terminator at end of content
|
//changed to add null terminator at end of content
|
||||||
//content length = (length in bytes of property set) + null char
|
//content length = (length in bytes of property set) + null char
|
||||||
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\nNT:"
|
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %ld\r\nNT:"
|
||||||
" upnp:event\r\nNTS: upnp:propchange\r\n",
|
" upnp:event\r\nNTS: upnp:propchange\r\n",
|
||||||
strlen( propertySet ) + 1 );
|
(long) strlen( propertySet ) + 1 );
|
||||||
|
|
||||||
HandleLock( );
|
HandleLock( );
|
||||||
|
|
||||||
@@ -1166,7 +1167,7 @@ respond_ok( IN SOCKINFO * info,
|
|||||||
response.size_inc = 30;
|
response.size_inc = 30;
|
||||||
if( http_MakeMessage( &response, major, minor,
|
if( http_MakeMessage( &response, major, minor,
|
||||||
"R" "D" "S" "N" "Xc" "ssc" "sc" "c",
|
"R" "D" "S" "N" "Xc" "ssc" "sc" "c",
|
||||||
HTTP_OK, 0,
|
HTTP_OK, 0, X_USER_AGENT,
|
||||||
"SID: ", sub->sid, timeout_str ) != 0 ) {
|
"SID: ", sub->sid, timeout_str ) != 0 ) {
|
||||||
membuffer_destroy( &response );
|
membuffer_destroy( &response );
|
||||||
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
|
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
|
||||||
|
Reference in New Issue
Block a user