Example #1
0
def fork_in_bg(function, *args):
    # fork and call a function with args
    #  return a dict with {'r': fd, 'pid': pid} where fd is the stdout from a pipe.
    #    example:
    #      def add(i, j): return i+j
    #      d = fork_in_bg(add, i, j)

    r, w = os.pipe()
    unregister_sighandler()
    pid = os.fork()
    if pid == 0:
        logSupport.disable_rotate = True
        os.close(r)
        try:
            out = function(*args)
            os.write(w, cPickle.dumps(out))
        except:
            logSupport.log.warning("Forked process '%s' failed" % str(function))
            logSupport.log.exception("Forked process '%s' failed" % str(function))
        finally:
            os.close(w)
            # Exit, immediately. Don't want any cleanup, since I was created
            # just for performing the work
            os._exit(0)
    else:
        register_sighandler()
        os.close(w)

    return {'r': r, 'pid': pid}
Example #2
0
 def start_background_cleanup(self):
     if self.cleanup_pids:
         logSupport.log.warning("Earlier cleanup PIDs %s still exist; skipping this cycle" %
                                self.cleanup_pids)
     else:
         num_forks = 4 # arbitrary - could be configurable
         cleanup_lists = [self.cleanup_objects[x::num_forks] for x in xrange(num_forks)]
         for i in xrange(num_forks):
             unregister_sighandler()
             cl_pid = os.fork()
             if cl_pid != 0:
                 register_sighandler()
                 self.cleanup_pids.append(cl_pid)
             else:
                 for cleaner in cleanup_lists[i]:
                     cleaner.cleanup()
                 os._exit(0)
         logSupport.log.debug("Forked cleanup PIDS %s" % self.cleanup_pids)
         del cleanup_lists