Re: Function written in C, hangs on one machine and not another...

From: Douglas McNaught <doug(at)mcnaught(dot)org>
To: cgg007(at)yahoo(dot)com
Cc: Dennis Jenkins <dennis(dot)jenkins(at)sbcglobal(dot)net>, postgresql listserv <pgsql-general(at)postgresql(dot)org>
Subject: Re: Function written in C, hangs on one machine and not another...
Date: 2005-10-28 21:04:11
Message-ID: m2ek65icac.fsf@Douglas-McNaughts-Powerbook.local
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

CG <cgg007(at)yahoo(dot)com> writes:

> Thanks to the great suggestions I've at least gotten it to not hang...
>
> Martijn's hint about blocking led me to open up those filehandles in
> a non-blocking mode. It appears that write() will write, at a
> maximum, only 4096 bytes when it is called from within
> PostgreSQL. I've tried to push data into it in <=4096-byte slugs,
> but after 4096 bytes it just won't take anymore. Since (I think)
> using a non-blocking mode could cause problems with thread safety,
> it's probably a lost cause.

It's not a thread safety issue--it's more that non-blocking I/O is
quite complicated to do properly.

> I'm new to C, so this may seem extremely naive: I'm not sure how to use exec()
> to solve this problem. Could you give me a few pointers to get me started?

The basic scheme would be:

* Write a standalone program that reads from stdin, does the
processing/analysis using the Adobe library, and writes its results
to stdout in some kind of easily-parseable format.
* In your backend function, create two pipes (one for input and one
for output), call fork(), close the appropriate file descriptors in
the parent and child, dup2() the pipe descriptors in the child onto
stdin and stdout, then:
* In the child process, exec() your standalone program.
* In the parent process, write all the data to the output pipe, then
read the results back from the input pipe. (This can be problematic
in the general case, but in yours it should be OK).
* When the child process (your program) finishes, you'll get an EOF on
the input descriptor in the parent processs. Close the input and
output pipes and do whatever you're supposed to do with the data you
read.

If the above doesn't make sense to you, you need to read up on Unix
programming. There are some good books on it, and I'm sure there's
lots of stuff on the web. The fork()/exec() pattern is very standard
stuff, but it's a little tricky to get at first.

This is not going to be tremendously efficient, but given the crap
library you have to deal with, it's the safest way.

-Doug

In response to

Browse pgsql-general by date

  From Date Subject
Next Message David Gama Rodrí­guez 2005-10-28 21:04:17 tsearch2 setweight
Previous Message Benjamin Smith 2005-10-28 20:47:49 Frequency of Analyze?