1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/****************************************************************
* *
* Copyright (c) 2001-2024 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_unistd.h"
#include <errno.h>
#include "error.h"
#include "io.h"
#include "iottdef.h"
#include "gtmio.h"
#include "gt_timer.h"
#include "send_msg.h"
#include "have_crit.h"
#include "iott_flush_time.h"
#include "deferred_events.h"
#include "deferred_events_queue.h"
GBLREF boolean_t prin_out_dev_failure;
GBLREF int process_exiting;
GBLREF int4 error_condition;
GBLREF io_pair io_curr_device, io_std_device;
error_def(ERR_TERMHANGUP);
error_def(ERR_TERMWRITE);
void iott_flush_buffer(io_desc *io_ptr, boolean_t new_write_flag)
{
d_tt_struct *tt_ptr;
int4 status;
ssize_t write_len;
boolean_t ch_set;
tt_ptr = io_ptr->dev_sp;
if (!tt_ptr->write_active)
return; /* Was assert but that ended up causing endless loops -- now we just survive */
ESTABLISH_GTMIO_CH(&io_ptr->pair, ch_set);
write_len = (ssize_t)(tt_ptr->tbuffp - tt_ptr->ttybuff);
if (0 < write_len)
{
DOWRITERC(tt_ptr->fildes, tt_ptr->ttybuff, write_len, status);
if ((0 == status) && (ERR_TERMHANGUP != error_condition))
{
tt_ptr->tbuffp = tt_ptr->ttybuff;
if (io_ptr == io_std_device.out)
{ /* ------------------------------------------------
* set prin_out_dev_failure to FALSE in case it
* had been set TRUE earlier and is now working.
* for eg. a write fails and the next write works.
* ------------------------------------------------
*/
prin_out_dev_failure = FALSE;
}
} else /* (0 != status) */
{
tt_ptr->write_active = FALSE; /* In case we come back this-a-way */
if ((io_ptr == io_std_device.out) && !prin_out_dev_failure)
{
send_msg_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_TERMWRITE, 0, status);
prin_out_dev_failure = TRUE; /* set flag for NOPRINCIO, to give app a chance */
}
xfer_set_handlers(defer_error, status, FALSE);
}
}
tt_ptr->write_active = new_write_flag;
REVERT_GTMIO_CH(&io_ptr->pair, ch_set);
}
void iott_flush(io_desc *io_ptr)
{
d_tt_struct *tt_ptr;
boolean_t ch_set;
ESTABLISH_GTMIO_CH(&io_ptr->pair, ch_set);
assert(tt == io_ptr->type);
tt_ptr = io_ptr->dev_sp;
if (tt_ptr->timer_set)
{
cancel_timer((TID)io_ptr);
tt_ptr->timer_set = FALSE;
}
if (tt_ptr->write_active)
{
REVERT_GTMIO_CH(&io_ptr->pair, ch_set);
return; /* We are nesting the buffer flush -- let original copy do its job */
}
tt_ptr->write_active = TRUE;
iott_flush_buffer(io_ptr, FALSE);
REVERT_GTMIO_CH(&io_ptr->pair, ch_set);
}
void iott_flush_time(TID id, int4 hd_len, io_desc **io_ptr_parm)
{
io_desc *io_ptr, *flush_parm;
d_tt_struct *tt_ptr;
boolean_t flush_immediately;
boolean_t ch_set;
io_ptr = *io_ptr_parm;
ESTABLISH_GTMIO_CH(&io_ptr->pair, ch_set);
assert(tt == io_ptr->type);
tt_ptr = io_ptr->dev_sp;
assert(tt_ptr->timer_set);
if ((FALSE == tt_ptr->write_active) && !prin_out_dev_failure) /* If not in write code and no failure already, do flush */
{
tt_ptr->timer_set = FALSE;
tt_ptr->write_active = TRUE;
iott_flush_buffer(io_ptr, FALSE);
} else /* doing write, reschedule the flush */
{ /* We cannot be starting unsafe timers during process exiting or in an interrupt-deferred window. */
flush_immediately = (process_exiting || (INTRPT_OK_TO_INTERRUPT != intrpt_ok_state));
assert(!flush_immediately || (FALSE == tt_ptr->write_active));
if (!flush_immediately)
{
flush_parm = io_ptr;
start_timer((TID)io_ptr,
IOTT_FLUSH_RETRY,
&iott_flush_time,
SIZEOF(flush_parm),
(char *)&flush_parm);
}
}
REVERT_GTMIO_CH(&io_ptr->pair, ch_set);
}
|