Terminate preforked process if the parent terminates abruptly

This commit is contained in:
Thomas Nagy 2015-02-14 15:04:09 +01:00
parent 5716e35fdd
commit f8ff53ef02
No known key found for this signature in database
GPG Key ID: 67A565EDFDF90E64
3 changed files with 43 additions and 2 deletions

View File

@ -25,7 +25,7 @@ To use::
The servers and the build process are using a shared nonce to prevent undesirable external connections.
"""
import os, re, socket, threading, sys, subprocess, time, atexit, traceback, random
import os, re, socket, threading, sys, subprocess, time, atexit, traceback, random, signal
try:
import SocketServer
except ImportError:
@ -157,6 +157,23 @@ def create_server(conn, cls):
SHARED_KEY = os.environ['SHARED_KEY']
os.environ['SHARED_KEY'] = ''
ppid = int(os.environ['PREFORKPID'])
def reap():
if os.sep != '/':
os.waitpid(ppid, 0)
else:
while 1:
try:
os.kill(ppid, 0)
except OSError:
break
else:
time.sleep(1)
os.kill(os.getpid(), signal.SIGKILL)
t = threading.Thread(target=reap)
t.setDaemon(True)
t.start()
SocketServer.TCPServer.allow_reuse_address = True
server = SocketServer.TCPServer(conn, req)
#server.timeout = 6000 # seconds
@ -338,6 +355,8 @@ else:
except KeyError:
key = "".join([chr(random.SystemRandom().randint(40, 126)) for x in range(20)])
os.environ['SHARED_KEY'] = ctx.SHARED_KEY = key
os.environ['PREFORKPID'] = str(os.getpid())
return key
def init_servers(ctx, maxval):
@ -357,6 +376,9 @@ else:
time.sleep(0.01)
if not conn:
raise ValueError('Could not start the server!')
if srv.poll() is not None:
Logs.warn('Looks like it it not our server process - concurrent builds are unsupported at this stage')
raise ValueError('Could not start the server')
CONNS.append(conn)
def init_smp(self):

View File

@ -2,6 +2,8 @@
# encoding: utf-8
# Thomas Nagy, 2015 (ita)
# TODO: have the child process terminate if the parent is killed abruptly
import os, re, socket, threading, sys, subprocess, time, atexit, traceback, random
try:
import SocketServer
@ -187,6 +189,7 @@ if 1:
except KeyError:
key = "".join([chr(random.SystemRandom().randint(40, 126)) for x in range(20)])
os.environ['SHARED_KEY'] = ctx.SHARED_KEY = key
os.environ['PREFORKPID'] = str(os.getpid())
return key
def init_servers(ctx, maxval):

View File

@ -19,7 +19,7 @@ To use::
more code
"""
import os, re, socket, threading, sys, subprocess, atexit, traceback
import os, re, socket, threading, sys, subprocess, atexit, traceback, signal, time
try:
from queue import Queue
except ImportError:
@ -136,9 +136,25 @@ if 1:
def make_conn(bld):
child_socket, parent_socket = socket.socketpair(socket.AF_UNIX)
ppid = os.getpid()
pid = os.fork()
if pid == 0:
parent_socket.close()
# if the parent crashes, try to exit cleanly
def reap():
while 1:
try:
os.kill(ppid, 0)
except OSError:
break
else:
time.sleep(1)
os.kill(os.getpid(), signal.SIGKILL)
t = threading.Thread(target=reap)
t.setDaemon(True)
t.start()
# write to child_socket only
try:
while 1: