📄 print.c
字号:
/*
* PROGRAM: JRD Lock Manager
* MODULE: print.c
* DESCRIPTION: Lock Table printer
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "../jrd/ib_stdio.h"
#include <stdlib.h>
#include <string.h>
#include "../jrd/common.h"
#include "../jrd/file_params.h"
#include "../jrd/jrd.h"
#include "../jrd/lck.h"
#include "../jrd/isc.h"
#include "../jrd/time.h"
#ifdef LINKS_EXIST
#include "../isc_lock/lock.h"
#else
#include "../lock/lock.h"
#endif /* LINKS_EXIST */
#include "../jrd/gdsassert.h"
#include "../jrd/gds_proto.h"
#include "../jrd/isc_proto.h"
#include "../jrd/isc_s_proto.h"
#include "../lock/prtv3_proto.h"
#if (defined DELTA || defined sgi || defined ultrix)
#include <sys/types.h>
#endif
#include <sys/stat.h>
#if !(defined mpexl || defined WIN_NT || defined OS2_ONLY)
#include <sys/param.h>
#endif
#if (defined WIN_NT || defined OS2_ONLY)
#include <winbase.h>
#include <io.h>
#include <process.h>
#endif
#ifdef NETWARE_386
typedef struct blk {
UCHAR blk_type;
UCHAR blk_pool_id_mod;
USHORT blk_length;
} *BLK;
#include "../jrd/svc.h"
#include "../jrd/svc_proto.h"
#define exit(code) {service->svc_handle = 0; \
\
/* Mark service thread as finished. */ \
/* If service is detached, cleanup memory being used \
by service. */ \
SVC_finish (service, SVC_finished); \
\
return (code);}
#define FPRINTF SVC_netware_fprintf
#endif
#ifndef FPRINTF
#define FPRINTF ib_fprintf
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#ifdef NETWARE_386
typedef SVC OUTFILE;
#else
typedef IB_FILE *OUTFILE;
#endif
#define SW_I_ACQUIRE 1
#define SW_I_OPERATION 2
#define SW_I_TYPE 4
#define SW_I_WAIT 8
struct waitque {
USHORT waitque_depth;
PTR waitque_entry [30];
};
#define COUNT(x) (sizeof (x)/ sizeof ((x)[0]))
static void prt_lock_activity (OUTFILE, LHB, USHORT, USHORT, USHORT);
static void prt_lock_init (void);
static void prt_history (OUTFILE, LHB, PTR, SCHAR *);
static void prt_lock (OUTFILE, LHB, LBL, USHORT);
static void prt_owner (OUTFILE, LHB, OWN, BOOLEAN, BOOLEAN);
static void prt_owner_wait_cycle (OUTFILE, LHB, OWN, USHORT, struct waitque *);
static void prt_request (OUTFILE, LHB, LRQ);
static void prt_que (OUTFILE, LHB, SCHAR *, SRQ, USHORT);
static void prt_que2 (OUTFILE, LHB, SCHAR *, SRQ, USHORT);
static CONST TEXT history_names[][10] = {
"n/a", "ENQ", "DEQ", "CONVERT", "SIGNAL", "POST", "WAIT",
"DEL_PROC", "DEL_LOCK", "DEL_REQ", "DENY", "GRANT", "LEAVE",
"SCAN", "DEAD", "ENTER", "BUG", "ACTIVE", "CLEANUP", "DEL_OWNER"
};
static CONST UCHAR compatibility[] = {
/* Shared Prot Shared Prot
none null Read Read Write Write Exclusive */
/* none */ 1, 1, 1, 1, 1, 1, 1,
/* null */ 1, 1, 1, 1, 1, 1, 1,
/* SR */ 1, 1, 1, 1, 1, 1, 0,
/* PR */ 1, 1, 1, 1, 0, 0, 0,
/* SW */ 1, 1, 1, 0, 1, 0, 0,
/* PW */ 1, 1, 1, 0, 0, 0, 0,
/* EX */ 1, 1, 0, 0, 0, 0, 0 };
#define COMPATIBLE(st1, st2) compatibility [st1 * LCK_max + st2]
#ifdef NETWARE_386
int main_lock_print (
SVC service)
#else /* Non-Netware declaration */
int CLIB_ROUTINE main (
int argc,
char *argv[])
#endif
{
/**************************************
*
* m a i n
*
**************************************
*
* Functional description
* Check switches passed in and prepare to dump the lock table
* to ib_stdout.
*
**************************************/
BOOLEAN sw_requests, sw_owners, sw_locks, sw_history, sw_nobridge;
USHORT sw_series, sw_interactive, sw_intervals, sw_seconds;
BOOLEAN sw_consistency;
BOOLEAN sw_waitlist;
BOOLEAN sw_file;
LHB LOCK_header, header = NULL;
SLONG LOCK_size_mapped = DEFAULT_SIZE;
int orig_argc;
SCHAR **orig_argv;
TEXT *lock_file, buffer [MAXPATHLEN];
TEXT expanded_lock_filename [MAXPATHLEN];
TEXT hostname [64];
USHORT i;
SLONG length;
SH_MEM_T shmem_data;
SHB shb;
SRQ que, slot;
SCHAR *p, c;
STATUS status_vector [20];
SLONG redir_in, redir_out, redir_err;
SLONG hash_total_count, hash_lock_count, hash_min_count, hash_max_count;
float bottleneck;
#ifdef NETWARE_386
int argc;
char **argv;
#endif
OUTFILE outfile;
#ifdef MANAGER_PROCESS
OWN manager;
int manager_pid;
#endif
#ifdef NETWARE_386
argc = service->svc_argc;
argv = service->svc_argv;
#endif
#ifdef NETWARE_386
outfile = service;
#else
outfile = ib_stdout;
#endif
/* Perform some special handling when run as an Interbase service. The
first switch can be "-svc" (lower case!) or it can be "-svc_re" followed
by 3 file descriptors to use in re-directing ib_stdin, ib_stdout, and ib_stderr. */
if (argc > 1 && !strcmp (argv [1], "-svc"))
{
argv++;
argc--;
#ifdef NETWARE_386
/* Get the output file name from the next argv[] etc. */
#endif
}
#ifndef NETWARE_386
else if (argc > 4 && !strcmp (argv [1], "-svc_re"))
{
redir_in = atol (argv [2]);
redir_out = atol (argv [3]);
redir_err = atol (argv [4]);
#ifdef WIN_NT
redir_in = _open_osfhandle (redir_in, 0);
redir_out = _open_osfhandle (redir_out, 0);
redir_err = _open_osfhandle (redir_err, 0);
#endif
if (redir_in != 0)
if (dup2 ((int) redir_in, 0))
close ((int) redir_in);
if (redir_out != 1)
if (dup2 ((int) redir_out, 1))
close ((int) redir_out);
if (redir_err != 2)
if (dup2 ((int) redir_err, 2))
close ((int) redir_err);
argv += 4;
argc -= 4;
}
#endif
orig_argc = argc;
orig_argv = argv;
/* Handle switches, etc. */
argv++;
sw_consistency = FALSE;
sw_waitlist = FALSE;
sw_file = FALSE;
sw_requests = sw_locks = sw_history = sw_nobridge = FALSE;
sw_owners = TRUE;
sw_series = sw_interactive = sw_intervals = sw_seconds = 0;
while (--argc)
{
p = *argv++;
if (*p++ != '-')
{
FPRINTF (outfile, "Valid switches are: -o, -p, -l, -r, -a, -h, -n, -s <n>, -c, -i <n> <n>\n");
exit(FINI_OK);
}
while (c = *p++)
switch (c)
{
case 'o':
case 'p':
sw_owners = TRUE;
break;
case 'c':
sw_nobridge = TRUE;
sw_consistency = TRUE;
break;
case 'l':
sw_locks = TRUE;
break;
case 'r':
sw_requests = TRUE;
break;
case 'a':
sw_locks = TRUE;
sw_owners = TRUE;
sw_requests = TRUE;
sw_history = TRUE;
break;
case 'h':
sw_history = TRUE;
break;
case 's':
if (argc > 1)
sw_series = atoi (*argv++);
if (!sw_series)
{
FPRINTF (outfile, "Please specify a positive value following option -s\n");
exit (FINI_OK);
}
--argc;
break;
case 'n':
sw_nobridge = TRUE;
break;
case 'i':
while (c = *p++)
switch (c)
{
case 'a':
sw_interactive |= SW_I_ACQUIRE;
break;
case 'o':
sw_interactive |= SW_I_OPERATION;
break;
case 't':
sw_interactive |= SW_I_TYPE;
break;
case 'w':
sw_interactive |= SW_I_WAIT;
break;
default:
FPRINTF (outfile, "Valid interactive switches are: a, o, t, w\n");
exit (FINI_OK);
break;
}
if (!sw_interactive)
sw_interactive = (SW_I_ACQUIRE | SW_I_OPERATION | SW_I_TYPE | SW_I_WAIT);
sw_nobridge = TRUE;
sw_seconds = sw_intervals = 1;
if (argc > 1)
{
sw_seconds = atoi (*argv++);
--argc;
if (argc > 1)
{
sw_intervals = atoi (*argv++);
--argc;
}
if (!(sw_seconds > 0) || (sw_intervals < 0))
{
FPRINTF (outfile, "Please specify 2 positive values for option -i\n");
exit (FINI_OK);
}
}
--p;
break;
case 'w':
sw_nobridge = TRUE;
sw_waitlist = TRUE;
break;
case 'f':
sw_nobridge = TRUE;
sw_file = TRUE;
if (argc > 1)
{
lock_file = *argv++;
--argc;
}
else
{
FPRINTF (outfile, "Usage: -f <filename>\n");
exit (FINI_OK);
};
break;
default:
FPRINTF (outfile, "Valid switches are: -o, -p, -l, -r, -a, -h, -n, -s <n>, -c, -i <n> <n>\n");
exit (FINI_OK);
break;
}
}
if (!sw_file)
{
gds__prefix_lock (buffer, LOCK_FILE);
lock_file = buffer;
}
#ifdef UNIX
shmem_data.sh_mem_semaphores = 0;
#endif
#ifdef UNIX
LOCK_size_mapped = 0; /* Use length of existing segment */
#else
LOCK_size_mapped = DEFAULT_SIZE; /* length == 0 not supported by all non-UNIX */
#endif
LOCK_header = (LHB) ISC_map_file (status_vector,
lock_file,
prt_lock_init,
NULL_PTR,
-LOCK_size_mapped, /* Negative to NOT truncate file */
&shmem_data);
sprintf (expanded_lock_filename, lock_file,
ISC_get_host (hostname, sizeof (hostname)));
/* Make sure the lock file is valid - if it's a zero length file we
* can't look at the header without causing a BUS error by going
* off the end of the mapped region.
*/
if (LOCK_header && shmem_data.sh_mem_length_mapped < sizeof (struct lhb))
{
/* Mapped file is obviously too small to really be a lock file */
FPRINTF (outfile, "Unable to access lock table - file too small.\n%s\n",
expanded_lock_filename);
exit (FINI_OK);
}
if (LOCK_header && LOCK_header->lhb_length > shmem_data.sh_mem_length_mapped)
{
length = LOCK_header->lhb_length;
#if (!(defined UNIX) || (defined MMAP_SUPPORTED))
LOCK_header = (LHB) ISC_remap_file (status_vector, &shmem_data, length, FALSE);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -