85 lines
3.1 KiB
C
85 lines
3.1 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2011 Fidelity Information Services, Inc *
|
|
* *
|
|
* 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_stat.h"
|
|
#include "gtm_fcntl.h"
|
|
|
|
#include "gdsroot.h"
|
|
#include "gdsbt.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsfhead.h"
|
|
#include "filestruct.h"
|
|
#include "jnl.h"
|
|
#include "gtmio.h" /* for CLOSEFILE used by the F_CLOSE macro in JNL_FD_CLOSE */
|
|
#include "repl_sp.h" /* for F_CLOSE used by the JNL_FD_CLOSE macro */
|
|
#include "iosp.h" /* for SS_NORMAL used by the JNL_FD_CLOSE macro */
|
|
|
|
#include "heartbeat_timer.h"
|
|
#include "gt_timer.h"
|
|
#include "gtmimagename.h"
|
|
#include "dpgbldir.h"
|
|
#include "have_crit.h"
|
|
|
|
GBLREF volatile uint4 heartbeat_counter;
|
|
GBLREF boolean_t is_src_server;
|
|
GBLREF enum gtmImageTypes image_type;
|
|
GBLREF uint4 process_id;
|
|
|
|
void heartbeat_timer(void)
|
|
{
|
|
gd_addr *addr_ptr;
|
|
gd_region *r_top, *r_save, *r_local;
|
|
sgmnt_addrs *csa;
|
|
jnl_private_control *jpc;
|
|
int rc;
|
|
|
|
/* It will take heartbeat_counter about 1014 years to overflow. */
|
|
heartbeat_counter++;
|
|
/* Check every 1 minute if we have an older generation journal file open. If so, close it.
|
|
* The only exceptions are
|
|
* a) The source server can have older generations open and they should not be closed.
|
|
* b) If we are in the process of switching to a new journal file while we get interrupted
|
|
* by the heartbeat timer, we should not close the older generation journal file
|
|
* as it will anyways be closed by the mainline code. But identifying that we are in
|
|
* the midst of a journal file switch is tricky so we check if the process is in
|
|
* crit for this region and if so we skip the close this time and wait for the next heartbeat.
|
|
*/
|
|
if ((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) && !is_src_server
|
|
&& (0 == heartbeat_counter % NUM_HEARTBEATS_FOR_OLDERJNL_CHECK))
|
|
{
|
|
for (addr_ptr = get_next_gdr(NULL); addr_ptr; addr_ptr = get_next_gdr(addr_ptr))
|
|
{
|
|
for (r_local = addr_ptr->regions, r_top = r_local + addr_ptr->n_regions; r_local < r_top; r_local++)
|
|
{
|
|
if (!r_local->open || r_local->was_open)
|
|
continue;
|
|
if ((dba_bg != r_local->dyn.addr->acc_meth) && (dba_mm != r_local->dyn.addr->acc_meth))
|
|
continue;
|
|
csa = &FILE_INFO(r_local)->s_addrs;
|
|
if (csa->now_crit)
|
|
continue;
|
|
jpc = csa->jnl;
|
|
if ((NULL != jpc) && (NOJNL != jpc->channel) && JNL_FILE_SWITCHED(jpc))
|
|
{ /* The journal file we have as open is not the latest generation journal file. Close it */
|
|
/* Assert that we never have an active write on a previous generation journal file. */
|
|
assert(process_id != jpc->jnl_buff->io_in_prog_latch.u.parts.latch_pid);
|
|
JNL_FD_CLOSE(jpc->channel, rc); /* sets jpc->channel to NOJNL */
|
|
jpc->pini_addr = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
start_timer((TID)heartbeat_timer, HEARTBEAT_INTERVAL, heartbeat_timer, 0, NULL);
|
|
}
|