Skip to content

Commit c34d279

Browse files
committed
#3 added restart delay (optional) to crash silently + cosmetic
1 parent 143503b commit c34d279

File tree

1 file changed

+44
-40
lines changed

1 file changed

+44
-40
lines changed

src/php-cgi-spawner.c

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
#include <ws2tcpip.h>
1+
#include <winsock.h>
22

33
#pragma comment( lib, "kernel32.lib")
44
#pragma comment( lib, "ws2_32.lib")
5-
#pragma warning( disable: 4701 )
65

76
__forceinline void memzero( void * mem, size_t size ) // anti memset
87
{
9-
do
10-
{
11-
( (volatile char *)mem )[--size] = 0;
12-
}
13-
while( size );
8+
while( size-- )
9+
( (volatile char *)mem )[size] = 0;
1410
}
1511

1612
#define MAX_SPAWN_HANDLES MAXIMUM_WAIT_OBJECTS
1713

18-
__forceinline void spawner( char * app, unsigned port, unsigned cgis )
1914
// based on spawn-fcgi-win32.c
2015
// found here: http://redmine.lighttpd.net/boards/2/topics/686#message-689
16+
__forceinline void spawner( char * app, unsigned port, unsigned cgis,
17+
unsigned restart_delay )
2118
{
2219
SOCKET s;
2320

@@ -52,7 +49,7 @@ __forceinline void spawner( char * app, unsigned port, unsigned cgis )
5249
return;
5350
}
5451

55-
if( -1 == bind( s, (struct sockaddr *)&fcgi_addr_in,
52+
if( -1 == bind( s, ( struct sockaddr * )&fcgi_addr_in,
5653
sizeof( fcgi_addr_in ) ) )
5754
return;
5855
}
@@ -64,13 +61,17 @@ __forceinline void spawner( char * app, unsigned port, unsigned cgis )
6461
if( !SetProcessShutdownParameters( 0x380, SHUTDOWN_NORETRY ) )
6562
return;
6663

64+
// php-cgis crash silently if restart delay is 1 second or more
65+
// (https://github.com/deemru/php-cgi-spawner/issues/3)
66+
if( restart_delay >= 1000 )
67+
SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX );
68+
6769
{
6870
HANDLE hProcesses[MAX_SPAWN_HANDLES];
6971
PROCESS_INFORMATION pi;
7072
STARTUPINFOA si;
7173
unsigned i;
7274

73-
memzero( hProcesses, sizeof( hProcesses ) );
7475
memzero( &si, sizeof( si ) );
7576

7677
si.cb = sizeof( STARTUPINFO );
@@ -79,49 +80,47 @@ __forceinline void spawner( char * app, unsigned port, unsigned cgis )
7980
si.hStdError = INVALID_HANDLE_VALUE;
8081
si.hStdInput = (HANDLE)s;
8182

83+
for( i = 0; i < cgis; i++ )
84+
hProcesses[i] = INVALID_HANDLE_VALUE;
85+
8286
for( ;; )
8387
{
84-
BOOL isSpawnNeed = FALSE;
85-
8688
for( i = 0; i < cgis; i++ )
8789
{
88-
if( hProcesses[i] != NULL )
90+
if( hProcesses[i] == INVALID_HANDLE_VALUE )
8991
{
90-
DWORD dwExitCode;
91-
if( !GetExitCodeProcess( hProcesses[i], &dwExitCode ) )
92+
if( !CreateProcessA( NULL, app, NULL, NULL, TRUE,
93+
CREATE_NO_WINDOW, NULL, NULL,
94+
&si, &pi ) )
9295
return;
9396

94-
if( dwExitCode != STILL_ACTIVE )
95-
{
96-
CloseHandle( hProcesses[i] );
97-
hProcesses[i] = NULL;
98-
isSpawnNeed = TRUE;
99-
}
100-
}
101-
else
102-
{
103-
isSpawnNeed = TRUE;
97+
CloseHandle( pi.hThread );
98+
hProcesses[i] = pi.hProcess;
10499
}
105100
}
106101

107-
if( isSpawnNeed )
102+
WaitForMultipleObjects( cgis, &hProcesses[0], FALSE, INFINITE );
103+
104+
for( i = 0; i < cgis; i++ )
108105
{
109-
for( i = 0; i < cgis; i++ )
106+
if( hProcesses[i] != INVALID_HANDLE_VALUE )
110107
{
111-
if( hProcesses[i] == NULL )
112-
{
113-
if( !CreateProcessA( NULL, app, NULL, NULL, TRUE,
114-
CREATE_NO_WINDOW, NULL, NULL,
115-
&si, &pi ) )
116-
return;
108+
DWORD dwExitCode;
109+
if( !GetExitCodeProcess( hProcesses[i], &dwExitCode ) )
110+
return;
117111

118-
CloseHandle( pi.hThread );
119-
hProcesses[i] = pi.hProcess;
112+
if( dwExitCode != STILL_ACTIVE )
113+
{
114+
CloseHandle( hProcesses[i] );
115+
hProcesses[i] = INVALID_HANDLE_VALUE;
120116
}
121117
}
122118
}
123119

124-
WaitForMultipleObjects( cgis, &hProcesses[0], FALSE, INFINITE );
120+
// optional restart delay
121+
// (https://github.com/deemru/php-cgi-spawner/issues/3)
122+
if( restart_delay )
123+
Sleep( restart_delay );
125124
}
126125
}
127126
}
@@ -210,14 +209,19 @@ __forceinline unsigned getargs( char * cmd, char ** argv, unsigned max )
210209
return argc;
211210
}
212211

213-
#define ARGS_COUNT 4
212+
#define ARGS_MAX 5
213+
#define ARGS_MIN 4
214214

215215
void __cdecl WinMainCRTStartup()
216216
{
217-
char * argv[ARGS_COUNT];
217+
char * argv[ARGS_MAX];
218+
argv[4] = NULL;
218219

219-
if( ARGS_COUNT == getargs( GetCommandLineA(), (char **)&argv, ARGS_COUNT ) )
220-
spawner( argv[1], char2num( argv[2] ), char2num( argv[3] ) );
220+
if( ARGS_MIN <= getargs( GetCommandLineA(), (char **)&argv, ARGS_MAX ) )
221+
{
222+
spawner( argv[1], char2num( argv[2] ), char2num( argv[3] ),
223+
argv[4] ? char2num( argv[4] ) : 0 );
224+
}
221225

222226
ExitProcess( 0 );
223227
}

0 commit comments

Comments
 (0)