📄 driver.c
字号:
/*
* PROGRAM: JRD Lock Manager
* MODULE: driver.c
* DESCRIPTION: Stand alone test driver
*
* 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 "../jrd/common.h"
#include "../jrd/gds.h"
#include "../jrd/isc.h"
#ifdef LINKS_EXIST
#include "../isc_lock/lock.h"
#else
#include "../lock/lock.h"
#endif
#ifdef WIN_NT
#include <process.h>
#endif
static void ast (int);
static int lookup_agg (UCHAR *);
static int lookup_lock (UCHAR *);
static void print_help (void);
static struct tbl {
SCHAR *tbl_string;
SSHORT tbl_code;
} types [] = {
"null", LCK_null,
"pr", LCK_PR,
"sr", LCK_SR,
"pw", LCK_PW,
"sw", LCK_SW,
"ex", LCK_EX,
NULL, LCK_none};
static struct tagg {
SCHAR *tagg_string;
SSHORT tagg_code;
} aggs [] = {
"min", LCK_MIN,
"max", LCK_MAX,
"cnt", LCK_CNT,
"sum", LCK_SUM,
"avg", LCK_AVG,
"any", LCK_ANY,
NULL, NULL};
static int wait, sw_release, locks [100], levels [100];
static SLONG lck_owner_handle = 0;
void main (
int argc,
char **argv)
{
/**************************************
*
* m a i n
*
**************************************
*
* Functional description
* Test driver for lock manager.
*
**************************************/
UCHAR op [500], arg [500];
SSHORT type, slot, n, agg;
SLONG lock, parent, data;
STATUS status, status_vector [20];
ib_printf ("\nStand alone Lock Manager driver program.\n");
ib_printf ("****************************************\n\n");
ib_printf ("pid = %d\n\n", getpid());
ib_printf ("\n");
if (LOCK_init (status_vector, TRUE,
(SLONG) getpid(), 1, &lck_owner_handle))
{
ib_printf ("LOCK_init failed\n");
gds__print_status (status_vector);
exit (0);
}
wait = 1;
sw_release = 1;
slot = 0;
/* Force a dummy parent lock to test query data functionality */
parent = LOCK_enq (
NULL, /* prior request */
NULL, /* parent request */
0, /* series */
"parent", /* value */
strlen ("parent"), /* length of key */
LCK_SR, /* lock type */
NULL, NULL, /* AST and argument */
0,
wait,
status_vector,
lck_owner_handle);
while (TRUE)
{
ib_printf ("Request: ");
status = ib_scanf ("%s%s", op, arg);
if (status == EOF)
continue;
if (!strcmp (op, "rel"))
{
n = atoi (arg);
if (n < slot && (lock = locks [n]))
{
LOCK_deq (lock);
locks [n] = 0;
}
else
ib_printf ("*** BAD LOCK\n");
continue;
}
else if (!strcmp (op, "ar"))
{
sw_release = atoi (arg);
continue;
}
else if (!strcmp (op, "w"))
{
wait = atoi (arg);
continue;
}
else if (!strcmp (op, "q"))
exit (0);
else if (!strcmp (op, "rd"))
{
n = atoi (arg);
if (n >= slot || !(lock = locks [n]))
{
ib_printf ("bad lock\n");
continue;
}
data = LOCK_read_data (lock);
ib_printf ("lock data = %d\n", data);
continue;
}
else if (!strcmp (op, "wd"))
{
n = atoi (arg);
if (n >= slot || !(lock = locks [n]))
{
ib_printf ("bad lock\n");
continue;
}
ib_scanf ("%s", arg);
data = atoi (arg);
LOCK_write_data (lock, data);
continue;
}
else if (!strcmp (op, "qd"))
{
if (!(agg = lookup_agg (arg)))
{
ib_printf ("bad query aggregate\n");
continue;
}
data = LOCK_query_data (parent, 0, agg);
if (agg == LCK_ANY)
ib_printf ("%s = %s\n", arg, ((data) ? "true" : "false"));
else
ib_printf ("%s = %d\n", arg, data);
continue;
}
else if (!strcmp (op, "cvt"))
{
n = atoi (arg);
ib_scanf ("%s", op);
if (!(type = lookup_lock (op)))
{
ib_printf ("bad lock type\n");
continue;
}
if (n >= slot || !(lock = locks [n]))
{
ib_printf ("bad lock\n");
continue;
}
if (!LOCK_convert (lock, type, wait, NULL, 0, status_vector))
{
ib_printf ("*** CONVERSION FAILED: status_vector[1] = %d", status_vector[1]);
if (status_vector[1] == gds__lock_timeout)
ib_printf(" (gds__lock_timeout)\n");
else
if (status_vector[1] == gds__lock_conflict)
ib_printf(" (gds__lock_conflict)\n");
else
if (status_vector[1] == gds__deadlock)
ib_printf(" (gds__deadlock)\n");
else
ib_printf("\n");
}
continue;
}
else if (type = lookup_lock (op))
{
lock = LOCK_enq (
NULL, /* prior request */
parent, /* parent request */
0, /* series */
arg, /* value */
strlen (arg), /* length of key */
type, /* lock type */
(sw_release ? ast : NULL), slot, /* AST and argument */
0,
wait,
status_vector,
lck_owner_handle);
if (lock)
{
ib_printf ("lock# %d = %d\n", slot, lock);
levels [slot] = type;
locks [slot++] = lock;
}
else
{
ib_printf ("*** LOCK REJECTED: status_vector[1] = %d", status_vector[1]);
if (status_vector[1] == gds__lock_timeout)
ib_printf(" (gds__lock_timeout)\n");
else
if (status_vector[1] == gds__lock_conflict)
ib_printf(" (gds__lock_conflict)\n");
else
if (status_vector[1] == gds__deadlock)
ib_printf(" (gds__deadlock)\n");
else
ib_printf("\n");
}
}
else
{
print_help();
continue;
}
}
}
static void ast (
int slot)
{
/**************************************
*
* a s t
*
**************************************
*
* Functional description
* Dummy blocking ast.
*
**************************************/
STATUS status_vector [20];
int sw_release_use = sw_release;
ib_printf ("*** blocking AST for lock# %d ", slot);
if (sw_release<0)
{
ib_printf ("In the AST routine.\n");
ib_printf ("Enter ar value [1=nothing, 2=release, 3=downgrade]:");
ib_scanf ("%d", &sw_release_use);
}
if (sw_release_use == 1)
{
ib_printf ("-- ignored ***\n");
return;
}
if (sw_release_use > 2 && levels [slot] == LCK_EX)
{
LOCK_convert (locks [slot], LCK_SR, wait, NULL, 0, status_vector);
levels [slot] = LCK_SR;
ib_printf ("-- down graded to SR ***\n");
return;
}
LOCK_deq (locks [slot]);
ib_printf ("-- released ***\n");
}
static lookup_agg (
UCHAR *string)
{
/**************************************
*
* l o o k u p _ a g g
*
**************************************
*
* Functional description
*
**************************************/
struct tagg *ptr;
for (ptr = aggs; ptr->tagg_string; ptr++)
if (strcmp (ptr->tagg_string, string) == 0)
return ptr->tagg_code;
return NULL;
}
static lookup_lock (
UCHAR *string)
{
/**************************************
*
* l o o k u p _ l o c k
*
**************************************
*
* Functional description
*
**************************************/
struct tbl *ptr;
for (ptr = types; ptr->tbl_string; ptr++)
if (strcmp (ptr->tbl_string, string) == 0)
return ptr->tbl_code;
return LCK_none;
}
static void print_help (void)
{
/**************************************
*
* p r i n t _ h e l p
*
**************************************
*
* Functional description
* Prints the command syntax.
*
***************************************/
ib_printf ("Command syntax is:\n");
ib_printf ("\tnull <key>\tAcquire an 'null' lock on <key> (returns <lock#>)\n");
ib_printf ("\tsr <key>\tAcquire an 'sr' lock on <key> (returns <lock#>)\n");
ib_printf ("\tpr <key>\tAcquire an 'pr' lock on <key> (returns <lock#>)\n");
ib_printf ("\tsw <key>\tAcquire an 'sw' lock on <key> (returns <lock#>)\n");
ib_printf ("\tpw <key>\tAcquire an 'pw' lock on <key> (returns <lock#>)\n");
ib_printf ("\tex <key>\tAcquire an 'ex' lock on <key> (returns <lock#>)\n");
ib_printf ("\tw <value>\tSet wait parameter to LOCK_enq:\n");
ib_printf ("\t\t\t\tvalue>0 willing to wait forever [default]\n");
ib_printf ("\t\t\t\tvalue=0 not willing to wait\n");
ib_printf ("\t\t\t\tvalue<0 willing to wait for that many seconds\n");
ib_printf ("\tar <value>\tControls the AST\n");
ib_printf ("\t\t\t\tvalue=1 AST will not release nor downgrade [default]\n");
ib_printf ("\t\t\t\tvalue=2 AST will release lock\n");
ib_printf ("\t\t\t\tvalue=3 AST will attempt to downgrade first\n");
ib_printf ("\t\t\t\tvalue<0 AST will prompt\n");
ib_printf ("\t\t\t\tvalue=0 AST is not supplied\n");
ib_printf ("\trel <lock#>\tRelease lock <lock#>\n");
ib_printf ("\tcvt <lock#> <lock-type>\n\t\t\tConvert lock <lock#> to type <lock-type>\n");
ib_printf ("\trd <lock#>\tRead data <lock#>\n");
ib_printf ("\twd <lock#> <data>\tWrite <data> to <lock#>\n");
ib_printf ("\tqd <agg>\tQuery data for <agg := min,max,cnt,sum,avg,any>\n");
ib_printf ("\tq <don't-care>\tQuit\n");
ib_printf ("\nRemember the isc_config modifier:\n");
ib_printf ("\tV4_LOCK_GRANT_ORDER {0 | 1}\n");
ib_printf ("\t\t\t0 = disable lock-grant-order (no lock-fairness)\n");
ib_printf ("\t\t\t1 = enable lock-grant-order [default]\n");
}
SCH_ast (void)
{
/**************************************
*
* S C H _ a s t
*
**************************************
*
* Functional description
* Stub to prevent link error
*
**************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -