[GRASS-dev] native WinGRASS and attribute data deadlock, next try
Moritz Lennert
mlennert at club.worldonline.be
Thu Oct 4 12:38:23 EDT 2007
On 24/09/07 03:41, Glynn Clements wrote:
> Moritz Lennert wrote:
>
>>> My next suggestion is to re-write xdr_stdio to use read() and write()
>>> instead of fread() and fwrite(), e.g.:
>>>
>>> - if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
>>> + if (read(fileno((FILE *)xdrs->x_private), (caddr_t)lp, sizeof(long)) !=
>>> sizeof(long))
>> That seems to work !
>
> Now that's strange. I was expecting it to provide more information on
> the errors, not to work.
>
> On Unix, read/write can return short counts on pipes. If a process
> tries to write 4 bytes to a pipe, and there's only enough space for 2
> bytes, write() will return 2 rather than waiting for the pipe to
> drain. Similarly if you try to read more data than is available in the
> pipe.
>
> If you want to block until the requested amount of data has been read
> or written, you need to either use readn/writen (which are
> non-standard), or implement them yourself, e.g.:
>
> ssize_t readn(int fd, void *buf, size_t count)
> {
> ssize_t total = 0;
>
> while (total < count)
> {
> ssize_t n = read(fd, (char *) buf + total, count - total)
> if (n < 0)
> return n;
> if (n == 0)
> break;
> total += n;
> }
>
> return total;
> }
>
> ssize_t writen(int fd, const void *buf, size_t count)
> {
> ssize_t total = 0;
>
> while (total < count)
> {
> ssize_t n = write(fd, (const char *) buf + total, count - total)
> if (n < 0)
> return n;
> if (n == 0)
> break;
> total += n;
> }
>
> return total;
> }
>
> The above assumes that non-blocking I/O hasn't been enabled for the
> descriptor. If it has, you need to either disable it for the duration
> of the function or use select() or poll() to wait until the descriptor
> is ready.
>
>> I'll post new binaries as soon as compilation is over, so that others can
>> test as well.
>
> If you want to test it, I'd suggest reducing the size of the pipes in
> lib/db/dbmi_client/start.c. A larger pipe won't prevent errors, but it
> may make them less likely to show up.
>
I changes the values in lines 146 & 147 and went down all the way to 2 (
from the current setting of 250000): I cannot reproduce the
deadlock...v.out.ogr works as it should.
So, where should we go from here ? Is it still wiser to implement
readn/writen as you suggest above ? If yes, where and how do I see if
non-blocking I/O is enabled or not (on MSDN it says: "In multithreaded
programs, no locking is performed. The file descriptors returned are
newly opened and should not be referenced by any thread until after the
_pipe call is complete." - Is this what you mean ?) ?
Benjamin, could you try the simple write/read (instead of fwrite/fread)
solution, so that we can make sure that this works for someone else ?
Moritz
More information about the grass-dev
mailing list