[GRASS-dev] Issues of 6.5 build on WinXP

Glynn Clements glynn at gclements.plus.com
Fri Jan 1 06:29:23 EST 2010


Glynn Clements wrote:

> 2. LayerSelect.InsertLayers() in gselect.py, which calls
> GetVectorNumberOfLayers() in utils.py, which runs
> "v.category option=report".

Reminder: this is what hangs the GUI if DEBUG= is set. It is run thus:

    ret = gcmd.RunCommand('v.category',
                          read = True,
                          input = vector,
                          option = 'report')

gcmd.RunCommand() does this:

    ret = ps.wait()
    
    stdout, stderr = ps.communicate()

which is why it hangs.

The ps.wait() call is bogus; it will block forever if stdout and/or
stderr are redirected to a pipe and the process writes more than
pathconf(..., _PC_PIPE_BUF) bytes to the pipe.

[This value will be at least 512; 4096 is typical.]

ps.communicate() feeds any input to stdin and reads stdin/stdout (if
those are pipes) until EOF, then calls the wait() method. The return
value from wait() is just self.returncode, so the above can be
re-written as:

    stdout, stderr = ps.communicate()

    ret = ps.returncode

Fixed in r40169 (trunk); back-porting recommended.

This issue is, in large part, why the communicate() method exists, and
why POSIX' popen() function only lets you pipe stdin or stdout, but
not both (or stderr).

Processing multiple descriptors without deadlock is non-trivial;
subprocess.communicate() provides a simple, portable method for the
case of a single pipe, and invokes a more complex, platform-specific
_communicate() method for two or more pipes (using select() on Unix
and threads on Windows).

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the grass-dev mailing list