diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 02db5b82dd..d65db76649 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,58 @@ 2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2009-03-07 19:56 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/common/hbgete.c + * added suport for BSD systems + + * harbour/contrib/examples/uhttpd/uhttpd.prg + ! fixed private declaration - after last modification they were not + declared for threads at all + ! fixed close procedure, s_aRunningThreads and s_aServiceThreads + where not protected at all in the moment when these variables + variables where used inside aeval() and other threads were + resizing them removing their pointers. In short word it was + in practice impossible to cleanly close uhttpd server without + GPF, deadlock or other bad side effects. I changed this code so + these arrays are modified only by calling procedure. + I do not know why it was written in such way but I guess it + was workaround for xHarbour bugs. In xHarbour is race condition + inside some functions like ThreadJoin() (RTE if thread finished + just before ThreadJoin()). Harbour does not have such + problems so I simply cleaned this code making it much simpler. + * reactivated hb_gcAll( .T. ) in the main loop for tests. + I made some tests with linux and current uhttpd works perfectly + without any problems with and without hb_gcAll( .t. ). + I haven't noticed any problems. I used this scripts to make + tests: + #!/bin/sh + function GT_UHTTPD() + { + while curl http://127.0.0.1:8082/ > /dev/null + do + if ! curl http://127.0.0.1:8082/serverstatus > /dev/null + then + exit + fi + # disable it if you want to increase traffic + if ! curl http://127.0.0.1:8082/info > /dev/null + then + exit + fi + if [ -f stop ] + then + exit + fi + done + } + for i in `seq 10` + do + GT_UHTTPD &>/dev/null & + done + wait + + on three CPU machine. Please make some test with other systems. + 2009-03-07 13:04 UTC+0100 Viktor Szakats (harbour.01 syenar hu) * contrib/examples/uhttpd/uhttpdgd.hbm + Added *nix GD lib name. diff --git a/harbour/contrib/examples/uhttpd/uhttpd.prg b/harbour/contrib/examples/uhttpd/uhttpd.prg index 51b21e0b69..e2222ad1bb 100644 --- a/harbour/contrib/examples/uhttpd/uhttpd.prg +++ b/harbour/contrib/examples/uhttpd/uhttpd.prg @@ -210,8 +210,6 @@ FUNCTION MAIN( ... ) LOCAL hDefault, cLogAccess, cLogError, cSessionPath LOCAL cCmdPort, cCmdDocumentRoot, lCmdIndexes, nCmdStartThreads, nCmdMaxThreads - PRIVATE _SERVER, _GET, _POST, _COOKIE, _SESSION, _REQUEST, _HTTP_REQUEST, m_cPost - IF !HB_MTVM() ? "I need multhread support. Please, recompile me!" WAIT @@ -554,7 +552,7 @@ FUNCTION MAIN( ... ) ENDIF // Memory release - //hb_GCAll( TRUE ) + hb_GCAll( TRUE ) ENDDO @@ -632,14 +630,21 @@ STATIC FUNCTION AcceptConnections() // Requesting to Running threads to quit (using -1 value) AEVAL( s_aRunningThreads, {|| hb_mutexNotify( s_hmtxRunningThreads, -1 ) } ) - // waiting running threads to quit - AEVAL( s_aRunningThreads, {|h| hb_threadJoin( h ) } ) - // Requesting to Service threads to quit (using -1 value) AEVAL( s_aServiceThreads, {|| hb_mutexNotify( s_hmtxServiceThreads, -1 ) } ) + + // waiting running threads to quit + AEVAL( s_aRunningThreads, {|h| hb_threadJoin( h ) } ) // waiting service threads to quit AEVAL( s_aServiceThreads, {|h| hb_threadJoin( h ) } ) + IF hb_mutexLock( s_hmtxBusy ) + //hb_ToOutDebug( "Len( s_aRunningThreads ) = %i\n\r", Len( s_aRunningThreads ) ) + asize( s_aRunningThreads, 0 ) + asize( s_aServiceThreads, 0 ) + hb_mutexUnlock( s_hmtxBusy ) + ENDIF + EXIT ENDIF @@ -718,6 +723,8 @@ STATIC FUNCTION ProcessConnection() LOCAL hSocket, nLen, cRequest, cSend LOCAL nMsecs, nParseTime, nPos, nThreadID + PRIVATE _SERVER, _GET, _POST, _COOKIE, _SESSION, _REQUEST, _HTTP_REQUEST, m_cPost + nThreadId := hb_threadID() //hb_ToOutDebug( "nThreadId = %s\r\n", nThreadId ) @@ -842,14 +849,6 @@ STATIC FUNCTION ProcessConnection() WriteToConsole( "Quitting ProcessConnections() " + hb_CStr( nThreadId ) ) - IF hb_mutexLock( s_hmtxBusy ) - //hb_ToOutDebug( "Len( s_aRunningThreads ) = %i\n\r", Len( s_aRunningThreads ) ) - IF ( nPos := aScan( s_aRunningThreads, hb_threadSelf() ) > 0 ) - hb_aDel( s_aRunningThreads, nPos, TRUE ) - s_nThreads := Len( s_aRunningThreads ) - ENDIF - hb_mutexUnlock( s_hmtxBusy ) - ENDIF RETURN 0 @@ -858,6 +857,8 @@ STATIC FUNCTION ServiceConnection() LOCAL nMsecs, nParseTime, nPos, nThreadId LOCAL nError := 500013 + PRIVATE _SERVER, _GET, _POST, _COOKIE, _SESSION, _REQUEST, _HTTP_REQUEST, m_cPost + ErrorBlock( { | oError | uhttpd_DefError( oError ) } ) nThreadId := hb_threadID() @@ -977,9 +978,6 @@ STATIC FUNCTION ServiceConnection() IF hb_mutexLock( s_hmtxBusy ) s_nServiceThreads-- - IF ( nPos := aScan( s_aServiceThreads, hb_threadSelf() ) > 0 ) - hb_aDel( s_aServiceThreads, nPos, TRUE ) - ENDIF hb_mutexUnlock( s_hmtxBusy ) ENDIF diff --git a/harbour/source/common/hbgete.c b/harbour/source/common/hbgete.c index 3241b654ae..3f54057a54 100644 --- a/harbour/source/common/hbgete.c +++ b/harbour/source/common/hbgete.c @@ -158,7 +158,7 @@ BOOL hb_setenv( const char * szName, const char * szValue ) #elif defined( _BSD_SOURCE ) || _POSIX_C_SOURCE >= 200112L || \ _XOPEN_SOURCE >= 600 || defined( __WATCOMC__ ) || defined( __DJGPP__ ) || \ - defined( HB_OS_DARWIN ) + defined( HB_OS_BSD ) || defined( HB_OS_DARWIN ) if( szValue ) return setenv( szName, szValue, 1 ) == 0;