Exemple #1
0
    def __init__(self, path, args=[], warnwords=[], env=None, chdir="."):
        GObject.GObject.__init__(self)

        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""

        self.linePublisher = EmitPublisher(self, "line",
                                           'SubProcess.linePublisher',
                                           EmitPublisher.SEND_LIST)

        self.linePublisher.start()

        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f", time.localtime(t)) %
                        (t % 60))
        log.debug(path, extra={"task": self.defname})

        argv = [str(u) for u in [self.path] + self.args]
        log.debug("SubProcess.__init__: spawning...",
                  extra={"task": self.defname})
        self.pid, stdin, stdout, stderr = GObject.spawn_async(
            argv,
            working_directory=chdir,
            child_setup=self.__setup,
            standard_input=True,
            standard_output=True,
            standard_error=True,
            flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH)

        log.debug("SubProcess.__init__: _initChannel...",
                  extra={"task": self.defname})
        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = GObject.IO_IN | GObject.IO_HUP  #|GObject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb,
                                            False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb,
                                            True)

        log.debug("SubProcess.__init__: channelsClosed...",
                  extra={"task": self.defname})
        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        log.debug("SubProcess.__init__: child_watch_add...",
                  extra={"task": self.defname})
        GObject.child_watch_add(self.pid, self.__child_watch_callback)

        log.debug("SubProcess.__init__: subprocExitCode...",
                  extra={"task": self.defname})
        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        subprocesses.append(self)
        log.debug("SubProcess.__init__: finished",
                  extra={"task": self.defname})
    def __init__(self, path, args=[], warnwords=[], env=None):
        gobject.GObject.__init__(self)

        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""

        self.linePublisher = EmitPublisher(self, "line",
                                           EmitPublisher.SEND_LIST)
        self.linePublisher.start()

        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f", time.localtime(t)) %
                        (t % 60))
        log.debug(path + "\n", self.defname)

        argv = [str(u) for u in [self.path] + self.args]
        self.pid, stdin, stdout, stderr = gobject.spawn_async(
            argv,
            child_setup=self.__setup,
            standard_input=True,
            standard_output=True,
            standard_error=True,
            flags=gobject.SPAWN_DO_NOT_REAP_CHILD | gobject.SPAWN_SEARCH_PATH)

        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = gobject.IO_IN | gobject.IO_HUP  #|gobject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb,
                                            False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb,
                                            True)

        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        gobject.child_watch_add(self.pid, self.__child_watch_callback)

        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        self.subprocFinishedEvent.clear()
        subprocesses.append(self)
        pool.start(self._wait4exit)
Exemple #3
0
 def __init__(self, path, args=[], warnwords=[], env=None, chdir="."):      
     GObject.GObject.__init__(self)
     
     self.path = path
     self.args = args
     self.warnwords = warnwords
     self.env = env or os.environ
     self.buffer = ""
     
     self.linePublisher = EmitPublisher(self, "line",
         'SubProcess.linePublisher', EmitPublisher.SEND_LIST)        
    
     self.linePublisher.start()        
    
     self.defname = os.path.split(path)[1]
     self.defname = self.defname[:1].upper() + self.defname[1:].lower()
     t = time.time()
     self.defname = (self.defname,
                     time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60))
     log.debug(path, extra={"task":self.defname})
     
     argv = [str(u) for u in [self.path]+self.args]
     log.debug("SubProcess.__init__: spawning...",  extra={"task":self.defname})
     self.pid, stdin, stdout, stderr = GObject.spawn_async(argv,
             working_directory=chdir, child_setup=self.__setup,
             standard_input=True, standard_output=True, standard_error=True,
             flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH)        
    
     log.debug("SubProcess.__init__: _initChannel...",  extra={"task":self.defname})
     self.__channelTags = []
     self.inChannel = self._initChannel(stdin, None, None, False)
     readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR
     self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False)
     self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True)
     
     log.debug("SubProcess.__init__: channelsClosed...",  extra={"task":self.defname})
     self.channelsClosed = False
     self.channelsClosedLock = threading.Lock()
     log.debug("SubProcess.__init__: child_watch_add...",  extra={"task":self.defname})
     GObject.child_watch_add(self.pid, self.__child_watch_callback)        
    
     log.debug("SubProcess.__init__: subprocExitCode...",  extra={"task":self.defname})
     self.subprocExitCode = (None, None)
     self.subprocFinishedEvent = threading.Event()
     subprocesses.append(self)
     log.debug("SubProcess.__init__: finished",  extra={"task":self.defname})
 def __init__(self, path, args=[], warnwords=[], env=None):
     gobject.GObject.__init__(self)
     
     self.path = path
     self.args = args
     self.warnwords = warnwords
     self.env = env or os.environ
     self.buffer = ""
     
     self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST)
     self.linePublisher.start()
     
     self.defname = os.path.split(path)[1]
     self.defname = self.defname[:1].upper() + self.defname[1:].lower()
     t = time.time()
     self.defname = (self.defname,
                     time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60))
     log.debug(path+"\n", self.defname)
     
     argv = [str(u) for u in [self.path]+self.args]
     self.pid, stdin, stdout, stderr = gobject.spawn_async(argv,
             child_setup=self.__setup,
             standard_input=True, standard_output=True, standard_error=True,
             flags=gobject.SPAWN_DO_NOT_REAP_CHILD|gobject.SPAWN_SEARCH_PATH)
     
     self.__channelTags = []
     self.inChannel = self._initChannel(stdin, None, None, False)
     readFlags = gobject.IO_IN|gobject.IO_HUP#|gobject.IO_ERR
     self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False)
     self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True)
     
     self.channelsClosed = False
     self.channelsClosedLock = threading.Lock()
     gobject.child_watch_add(self.pid, self.__child_watch_callback)
     
     self.subprocExitCode = (None, None)
     self.subprocFinishedEvent = threading.Event()
     self.subprocFinishedEvent.clear()
     subprocesses.append(self)
     pool.start(self._wait4exit)
Exemple #5
0
class SubProcess (GObject.GObject):
    
    __gsignals__ = {
        "line": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
        "died": (GObject.SignalFlags.RUN_FIRST, None, ())
    }




    def __init__(self, path, args=[], warnwords=[], env=None, chdir="."):      
        GObject.GObject.__init__(self)
        
        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""
        
        self.linePublisher = EmitPublisher(self, "line",
            'SubProcess.linePublisher', EmitPublisher.SEND_LIST)        
       
        self.linePublisher.start()        
       
        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60))
        log.debug(path, extra={"task":self.defname})
        
        argv = [str(u) for u in [self.path]+self.args]
        log.debug("SubProcess.__init__: spawning...",  extra={"task":self.defname})
        self.pid, stdin, stdout, stderr = GObject.spawn_async(argv,
                working_directory=chdir, child_setup=self.__setup,
                standard_input=True, standard_output=True, standard_error=True,
                flags=GObject.SPAWN_DO_NOT_REAP_CHILD|GObject.SPAWN_SEARCH_PATH)        
       
        log.debug("SubProcess.__init__: _initChannel...",  extra={"task":self.defname})
        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = GObject.IO_IN|GObject.IO_HUP#|GObject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True)
        
        log.debug("SubProcess.__init__: channelsClosed...",  extra={"task":self.defname})
        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        log.debug("SubProcess.__init__: child_watch_add...",  extra={"task":self.defname})
        GObject.child_watch_add(self.pid, self.__child_watch_callback)        
       
        log.debug("SubProcess.__init__: subprocExitCode...",  extra={"task":self.defname})
        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        subprocesses.append(self)
        log.debug("SubProcess.__init__: finished",  extra={"task":self.defname})
    
    def _initChannel (self, filedesc, callbackflag, callback, isstderr):        
        channel = GLib.IOChannel(filedesc)
        channel.set_encoding(None)
        if sys.platform != "win32":
            channel.set_flags(GObject.IO_FLAG_NONBLOCK)
        if callback:
            tag = channel.add_watch(callbackflag, callback, isstderr)
            self.__channelTags.append(tag)
        return channel
    
    def _closeChannels (self):
        self.channelsClosedLock.acquire()
        try:
            if self.channelsClosed == True:
                return
            self.channelsClosed = True
        finally:
            self.channelsClosedLock.release()

        for tag in self.__channelTags:
            GObject.source_remove(tag)
        for channel in (self.inChannel, self.outChannel, self.errChannel):
            try:
                channel.close()
            except GObject.GError as error:
                pass
    
    def __setup (self):
        os.nice(15)
    
    def __child_watch_callback (self, pid, code):
        log.debug("SubProcess.__child_watch_callback: %s" % repr(code), 
                  extra={"task":self.defname})
        # Kill the engine on any signal but 'Resource temporarily unavailable'
        self.subprocExitCode = (code, os.strerror(code))
        if code != errno.EWOULDBLOCK:
            if isinstance(code, str):
                log.error(code, extra={"task":self.defname})
            else: log.error(os.strerror(code), extra={"task":self.defname})
            self.emit("died")
            self.gentleKill()
    
    def __io_cb (self, channel, condition, isstderr):
        while True:
            try:
#                line = channel.next()#readline()
                line = channel.readline()
            except StopIteration:
                # fix for pygi
                #return False
                return True
            # Some engines send author names in different encodinds (f.e. spike)
            if line.startswith("id author") or not line:
                return True
            if isstderr:
                log.error(line, extra={"task":self.defname})
            else:
                for word in self.warnwords:
                    if word in line:
                        log.warning(line, extra={"task":self.defname})
                        break
                else: log.debug(line.rstrip(), extra={"task":self.defname})
            
            self.linePublisher.put(line)

    def write (self, data):
        if self.channelsClosed:
            log.warning("Chan closed for %r" % data, extra={"task":self.defname})
            return
        if data.rstrip():
            log.info(data, extra={"task":self.defname})
        self.inChannel.write(data)
        if data.endswith("\n"):
            try:
                self.inChannel.flush()
            except GObject.GError as e:
                log.error(str(e)+". Last line wasn't sent.", extra={"task":self.defname})

    def sendSignal (self, sign):
        try:
            if sys.platform != "win32":
                os.kill(self.pid, signal.SIGCONT)
            os.kill(self.pid, sign)
        except OSError as error:
            if error.errno == errno.ESRCH:
                #No such process
                pass
            else: raise OSError(error)
    
    def gentleKill (self, first=1, second=1):
        t = Thread(target=self.__gentleKill_inner,
                   name=fident(self.__gentleKill_inner),
                   args=(first, second))
        t.daemon = True
        t.start()
    
    def __gentleKill_inner (self, first, second):
        self.resume()
        self._closeChannels()
        time.sleep(first)
        code, string = self.subprocExitCode
        if code == None:
            self.sigterm()
            time.sleep(second)
            code, string = self.subprocExitCode
            if code == None:
                self.sigkill()
                self.subprocFinishedEvent.set()
                return self.subprocExitCode[0]
            self.subprocFinishedEvent.set()
            return code
        self.subprocFinishedEvent.set()
        self.linePublisher._del()
        return code
    
    def pause (self):
        self.sendSignal(signal.SIGSTOP)
    
    def resume (self):
        if sys.platform != "win32":
            self.sendSignal(signal.SIGCONT)
    
    def sigkill (self):
        self.sendSignal(signal.SIGKILL)
    
    def sigterm (self):
        self.sendSignal(signal.SIGTERM)
    
    def sigint (self):
        self.sendSignal(signal.SIGINT)
class SubProcess (gobject.GObject):
    
    __gsignals__ = {
        "line": (gobject.SIGNAL_RUN_FIRST, None, (object,)),
        "died": (gobject.SIGNAL_RUN_FIRST, None, ())
    }
    
    def __init__(self, path, args=[], warnwords=[], env=None):
        gobject.GObject.__init__(self)
        
        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""
        
        self.linePublisher = EmitPublisher(self, "line", EmitPublisher.SEND_LIST)
        self.linePublisher.start()
        
        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f",time.localtime(t)) % (t%60))
        log.debug(path+"\n", self.defname)
        
        argv = [str(u) for u in [self.path]+self.args]
        self.pid, stdin, stdout, stderr = gobject.spawn_async(argv,
                child_setup=self.__setup,
                standard_input=True, standard_output=True, standard_error=True,
                flags=gobject.SPAWN_DO_NOT_REAP_CHILD|gobject.SPAWN_SEARCH_PATH)
        
        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = gobject.IO_IN|gobject.IO_HUP#|gobject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb, False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb, True)
        
        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        gobject.child_watch_add(self.pid, self.__child_watch_callback)
        
        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        self.subprocFinishedEvent.clear()
        subprocesses.append(self)
        pool.start(self._wait4exit)
    
    def _initChannel (self, filedesc, callbackflag, callback, isstderr):
        channel = gobject.IOChannel(filedesc)
        if sys.platform != "win32":
            channel.set_flags(gobject.IO_FLAG_NONBLOCK)
        if callback:
            tag = channel.add_watch(callbackflag, callback, isstderr)
            self.__channelTags.append(tag)
        return channel
    
    def _closeChannels (self):
        self.channelsClosedLock.acquire()
        try:
            if self.channelsClosed == True:
                return
            self.channelsClosed = True
        finally:
            self.channelsClosedLock.release()

        for tag in self.__channelTags:
            gobject.source_remove(tag)
        for channel in (self.inChannel, self.outChannel, self.errChannel):
            try:
                channel.close()
            except gobject.GError, error:
                pass
Exemple #7
0
class SubProcess(GObject.GObject):

    __gsignals__ = {
        "line": (GObject.SignalFlags.RUN_FIRST, None, (object, )),
        "died": (GObject.SignalFlags.RUN_FIRST, None, ())
    }

    def __init__(self, path, args=[], warnwords=[], env=None, chdir="."):
        GObject.GObject.__init__(self)

        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""

        self.linePublisher = EmitPublisher(self, "line",
                                           'SubProcess.linePublisher',
                                           EmitPublisher.SEND_LIST)

        self.linePublisher.start()

        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f", time.localtime(t)) %
                        (t % 60))
        log.debug(path, extra={"task": self.defname})

        argv = [str(u) for u in [self.path] + self.args]
        log.debug("SubProcess.__init__: spawning...",
                  extra={"task": self.defname})
        self.pid, stdin, stdout, stderr = GObject.spawn_async(
            argv,
            working_directory=chdir,
            child_setup=self.__setup,
            standard_input=True,
            standard_output=True,
            standard_error=True,
            flags=GObject.SPAWN_DO_NOT_REAP_CHILD | GObject.SPAWN_SEARCH_PATH)

        log.debug("SubProcess.__init__: _initChannel...",
                  extra={"task": self.defname})
        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = GObject.IO_IN | GObject.IO_HUP  #|GObject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb,
                                            False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb,
                                            True)

        log.debug("SubProcess.__init__: channelsClosed...",
                  extra={"task": self.defname})
        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        log.debug("SubProcess.__init__: child_watch_add...",
                  extra={"task": self.defname})
        GObject.child_watch_add(self.pid, self.__child_watch_callback)

        log.debug("SubProcess.__init__: subprocExitCode...",
                  extra={"task": self.defname})
        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        subprocesses.append(self)
        log.debug("SubProcess.__init__: finished",
                  extra={"task": self.defname})

    def _initChannel(self, filedesc, callbackflag, callback, isstderr):
        channel = GLib.IOChannel(filedesc)
        if sys.platform != "win32":
            channel.set_flags(GObject.IO_FLAG_NONBLOCK)
        if callback:
            tag = channel.add_watch(callbackflag, callback, isstderr)
            self.__channelTags.append(tag)
        return channel

    def _closeChannels(self):
        self.channelsClosedLock.acquire()
        try:
            if self.channelsClosed == True:
                return
            self.channelsClosed = True
        finally:
            self.channelsClosedLock.release()

        for tag in self.__channelTags:
            GObject.source_remove(tag)
        for channel in (self.inChannel, self.outChannel, self.errChannel):
            try:
                channel.close()
            except GObject.GError as error:
                pass

    def __setup(self):
        os.nice(15)

    def __child_watch_callback(self, pid, code):
        log.debug("SubProcess.__child_watch_callback: %s" % repr(code),
                  extra={"task": self.defname})
        # Kill the engine on any signal but 'Resource temporarily unavailable'
        self.subprocExitCode = (code, os.strerror(code))
        if code != errno.EWOULDBLOCK:
            if isinstance(code, str):
                log.error(code, extra={"task": self.defname})
            else:
                log.error(os.strerror(code), extra={"task": self.defname})
            self.emit("died")
            self.gentleKill()

    def __io_cb(self, channel, condition, isstderr):
        while True:
            try:
                line = channel.next()  #readline()
            except StopIteration:
                # fix for pygi
                #return False
                return True
            if not line:
                return True
            if isstderr:
                log.error(line, extra={"task": self.defname})
            else:
                for word in self.warnwords:
                    if word in line:
                        log.warning(line, extra={"task": self.defname})
                        break
                else:
                    log.debug(line.rstrip(), extra={"task": self.defname})

            self.linePublisher.put(line)

    def write(self, data):
        if self.channelsClosed:
            log.warning("Chan closed for %r" % data,
                        extra={"task": self.defname})
            return
        if data.rstrip():
            log.info(data, extra={"task": self.defname})
        self.inChannel.write(data)
        if data.endswith("\n"):
            try:
                self.inChannel.flush()
            except GObject.GError as e:
                log.error(str(e) + ". Last line wasn't sent.",
                          extra={"task": self.defname})

    def sendSignal(self, sign):
        try:
            if sys.platform != "win32":
                os.kill(self.pid, signal.SIGCONT)
            os.kill(self.pid, sign)
        except OSError as error:
            if error.errno == errno.ESRCH:
                #No such process
                pass
            else:
                raise OSError(error)

    def gentleKill(self, first=1, second=1):
        t = Thread(target=self.__gentleKill_inner,
                   name=fident(self.__gentleKill_inner),
                   args=(first, second))
        t.daemon = True
        t.start()

    def __gentleKill_inner(self, first, second):
        self.resume()
        self._closeChannels()
        time.sleep(first)
        code, string = self.subprocExitCode
        if code == None:
            self.sigterm()
            time.sleep(second)
            code, string = self.subprocExitCode
            if code == None:
                self.sigkill()
                self.subprocFinishedEvent.set()
                return self.subprocExitCode[0]
            self.subprocFinishedEvent.set()
            return code
        self.subprocFinishedEvent.set()
        self.linePublisher._del()
        return code

    def pause(self):
        self.sendSignal(signal.SIGSTOP)

    def resume(self):
        if sys.platform != "win32":
            self.sendSignal(signal.SIGCONT)

    def sigkill(self):
        self.sendSignal(signal.SIGKILL)

    def sigterm(self):
        self.sendSignal(signal.SIGTERM)

    def sigint(self):
        self.sendSignal(signal.SIGINT)
class SubProcess(gobject.GObject):

    __gsignals__ = {
        "line": (gobject.SIGNAL_RUN_FIRST, None, (object, )),
        "died": (gobject.SIGNAL_RUN_FIRST, None, ())
    }

    def __init__(self, path, args=[], warnwords=[], env=None):
        gobject.GObject.__init__(self)

        self.path = path
        self.args = args
        self.warnwords = warnwords
        self.env = env or os.environ
        self.buffer = ""

        self.linePublisher = EmitPublisher(self, "line",
                                           EmitPublisher.SEND_LIST)
        self.linePublisher.start()

        self.defname = os.path.split(path)[1]
        self.defname = self.defname[:1].upper() + self.defname[1:].lower()
        t = time.time()
        self.defname = (self.defname,
                        time.strftime("%H:%m:%%.3f", time.localtime(t)) %
                        (t % 60))
        log.debug(path + "\n", self.defname)

        argv = [str(u) for u in [self.path] + self.args]
        self.pid, stdin, stdout, stderr = gobject.spawn_async(
            argv,
            child_setup=self.__setup,
            standard_input=True,
            standard_output=True,
            standard_error=True,
            flags=gobject.SPAWN_DO_NOT_REAP_CHILD | gobject.SPAWN_SEARCH_PATH)

        self.__channelTags = []
        self.inChannel = self._initChannel(stdin, None, None, False)
        readFlags = gobject.IO_IN | gobject.IO_HUP  #|gobject.IO_ERR
        self.outChannel = self._initChannel(stdout, readFlags, self.__io_cb,
                                            False)
        self.errChannel = self._initChannel(stderr, readFlags, self.__io_cb,
                                            True)

        self.channelsClosed = False
        self.channelsClosedLock = threading.Lock()
        gobject.child_watch_add(self.pid, self.__child_watch_callback)

        self.subprocExitCode = (None, None)
        self.subprocFinishedEvent = threading.Event()
        self.subprocFinishedEvent.clear()
        subprocesses.append(self)
        pool.start(self._wait4exit)

    def _initChannel(self, filedesc, callbackflag, callback, isstderr):
        channel = gobject.IOChannel(filedesc)
        if sys.platform != "win32":
            channel.set_flags(gobject.IO_FLAG_NONBLOCK)
        if callback:
            tag = channel.add_watch(callbackflag, callback, isstderr)
            self.__channelTags.append(tag)
        return channel

    def _closeChannels(self):
        self.channelsClosedLock.acquire()
        try:
            if self.channelsClosed == True:
                return
            self.channelsClosed = True
        finally:
            self.channelsClosedLock.release()

        for tag in self.__channelTags:
            gobject.source_remove(tag)
        for channel in (self.inChannel, self.outChannel, self.errChannel):
            try:
                channel.close()
            except gobject.GError, error:
                pass