This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Second patch ping


Ian Lance Taylor <ian@wasabisystems.com> writes:

> Zack Weinberg <zack@codesourcery.com> writes:
>
>> > http://gcc.gnu.org/ml/gcc-patches/2004-03/msg01445.html
>> >   Change collect2 to not call vfork, as a step toward making it
>> >   buildable on hosts which can not fork
>> 
>> I do not like the approach you have taken in libiberty.  Instead of
>> coming up with a general and *simple* interface that can handle both
>> what pexecute does now and what collect2 needs, you have invented a
>> new interface which is just as inflexible as pexecute, only it does
>> something slightly different, and furthermore it duplicates a lot of
>> code from pexecute.
>
> As I see it, the pexecute interface is overly general even today.  You
> can see this in pex-msdos.c, pex-os2.c, and pex-djgpp.c; the code
> calls abort if the caller does not pass both PEXECUTE_FIRST and
> PEXECUTE_LAST.  That means that the caller can not freely use
> pexecute; the caller must be aware of what capabilities are supported
> on the particular system.  Making the interface more general is likely
> to exacerbate that problem.

Well, now wait a minute, let's think about this.  Suppose we set out
to design an interface that didn't have that constraint, nor a bunch
of obnoxious other constraints (like -time requiring a bunch of custom
code in gcc.c and not working with -pipe; like the dance you have to
do in order to match pwait() results with the relevant processes; like
every last compiler spec having to have conditional code to handle -pipe).

That's my idea of a properly generalized interface.  And if done
right, it should also achieve what I originally asked for: one
interface that can do what gcc.c wants and what collect2.c wants.
And yes, I think it's an achievable goal.

All the operating systems of interest support 'launch-and-wait'
execution of programs: that is, there is a way to suspend the calling
process, create a new execution context, run a requested program in
the new context, and return control to the calling process when the
new program terminates.  Most of the OSs of interest also support
concurrent execution of more than one process, and all the ones that
do have pipes.  (Unix, VMS, Windows)

The desired functionality is to invoke a chain of processes, passing
the output of one to the input of the next, and possibly read the
output of the final program in the parent.  (Also, the parent might
like to supply the input to the first program in the chain, but we
have no immediate need for that.)

Here's how I would do it: Have an opaque object that encapsulates all
the state of the chain of processes being executed.  This is created
with one call, say pex_init().  That takes a set of flags: the current
two are PEX_USE_PIPES and PEX_RECORD_TIMES; both are requests, which
will not be honored if the necessary capabilities are not available.
(PEX_RECORD_TIMES perhaps should print a warning message in that
case.)

Then we cycle through calling pex_invoke(object, done, executable, argv)
which automatically connects the stdout of the first process to the
stdin of the next, using whatever means are appropriate (pipes or
temporary files).  The only flag we need here is 'done' which is a
boolean: is this the last process in the chain?  Note that that's to
be false in the case where the parent wants to read the final output.
pex_invoke waits for the child, and squirrels away the exit status, if
that's the only way it can be done or if pipes are not requested.

pex_read_output(object) returns a FILE* which the parent may read to
receive the output of the last process in the chain.

pex_get_status(object, count, vector) writes a vector of exit statuses
(requested length COUNT - that's just a sanity check) into vector,
which is an int*.  It blocks until all children are done executing if
they aren't already.

pex_get_times(object, count, vector) is the same but the vector is a
vector of rusage structures.  (Or we make up our own if that structure
isn't universal, which I suspect it is.)  This one will return an
error code if PEX_RECORD_TIMES wasn't set earlier.

Finally, pex_destroy() tears down the object.  It has no other
effects.

How's that sound?

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]