mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
Rename allow_buffering to piped_output_needs_buffering
This makes the variable's role clear. It controls whether output to a pipe must be buffered to avoid deadlock.
This commit is contained in:
parent
2d39568ec4
commit
171d09288b
23
src/exec.cpp
23
src/exec.cpp
|
@ -651,13 +651,13 @@ static proc_performer_t get_performer_for_process(process_t *p, job_t *job,
|
|||
}
|
||||
|
||||
/// Execute a block node or function "process".
|
||||
/// \p allow_buffering if true, permit buffering the output.
|
||||
/// \p piped_output_needs_buffering if true, buffer the output.
|
||||
static launch_result_t exec_block_or_func_process(parser_t &parser, const std::shared_ptr<job_t> &j,
|
||||
process_t *p, io_chain_t io_chain,
|
||||
bool allow_buffering) {
|
||||
bool piped_output_needs_buffering) {
|
||||
// Create an output buffer if we're piping to another process.
|
||||
shared_ptr<io_bufferfill_t> block_output_bufferfill{};
|
||||
if (!p->is_last_in_job && allow_buffering) {
|
||||
if (piped_output_needs_buffering) {
|
||||
// Be careful to handle failure, e.g. too many open fds.
|
||||
block_output_bufferfill = io_bufferfill_t::create();
|
||||
if (!block_output_bufferfill) {
|
||||
|
@ -783,15 +783,24 @@ static launch_result_t exec_process_in_job(parser_t &parser, process_t *p,
|
|||
parser.vars().set(assignment.variable_name, ENV_LOCAL | ENV_EXPORT, assignment.values);
|
||||
}
|
||||
|
||||
// Decide if outputting to a pipe may deadlock.
|
||||
// This happens if fish pipes from an internal process into another internal process:
|
||||
// echo $big | string match...
|
||||
// Here fish will only run one process at a time, so the pipe buffer may overfill.
|
||||
// It may also happen when piping internal -> external:
|
||||
// echo $big | external_proc
|
||||
// fish wants to run `echo` before launching external_proc, so the pipe may deadlock.
|
||||
// However if we are a deferred run, it means that we are piping into an external process
|
||||
// which got launched before us!
|
||||
bool piped_output_needs_buffering = !p->is_last_in_job && !is_deferred_run;
|
||||
|
||||
// Execute the process.
|
||||
p->check_generations_before_launch();
|
||||
switch (p->type) {
|
||||
case process_type_t::function:
|
||||
case process_type_t::block_node: {
|
||||
// Allow buffering unless this is a deferred run. If deferred, then processes after us
|
||||
// were already launched, so they are ready to receive (or reject) our output.
|
||||
bool allow_buffering = !is_deferred_run;
|
||||
if (exec_block_or_func_process(parser, j, p, process_net_io_chain, allow_buffering) ==
|
||||
if (exec_block_or_func_process(parser, j, p, process_net_io_chain,
|
||||
piped_output_needs_buffering) ==
|
||||
launch_result_t::failed) {
|
||||
return launch_result_t::failed;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user