which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
1202 lines
26 KiB
C
Executable File
1202 lines
26 KiB
C
Executable File
/* t4mul.c (c)Copyright Sequiter Software Inc., 1990-1993. All rights reserved. */
|
|
/* Tests Code Base multi-user. */
|
|
/* Run program from exactly two workstations. */
|
|
/* OR run program from exactly one Windows station */
|
|
|
|
#include "d4all.h"
|
|
#ifdef __TURBOC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#include "t4test.h"
|
|
|
|
#ifndef S4INDEX_OFF
|
|
|
|
#ifdef S4WINDOWS
|
|
/* currently just exclude conio */
|
|
#else
|
|
#ifdef S4UNIX
|
|
#ifdef S4CURSES
|
|
/* #include <curses.h> */
|
|
#else
|
|
/* #include <tinfo.h> */
|
|
#endif
|
|
#else
|
|
#include <conio.h>
|
|
#endif
|
|
#endif
|
|
|
|
#define WORK_WIDTH 10
|
|
|
|
static FIELD4INFO co_fields[] =
|
|
{
|
|
{ "COMMAND", 'C', WORK_WIDTH,0 },
|
|
{ "PARM", 'C', 8, 0 },
|
|
{ 0,0,0,0 },
|
|
} ;
|
|
|
|
static FIELD4INFO wo_fields[] =
|
|
{
|
|
{ "WORK", 'C', WORK_WIDTH,0 },
|
|
{ 0,0,0,0 },
|
|
} ;
|
|
|
|
static TAG4INFO wo_tags_one[] =
|
|
{
|
|
{ "TAG1", "WORK", 0,0,0 },
|
|
{ "TAG2", "WORK", 0,0,0 },
|
|
{ 0,0,0,0,0 },
|
|
} ;
|
|
|
|
static TAG4INFO wo_tags_two[] =
|
|
{
|
|
{ "TAG3", "WORK", 0,0,0 },
|
|
{ "TAG4", "WORK", 0,0,0 },
|
|
{ 0,0,0,0,0 },
|
|
} ;
|
|
|
|
static FIELD4INFO result_fields[] =
|
|
{
|
|
{ "RESULT", 'C', 8,0 },
|
|
{ 0,0,0,0 },
|
|
} ;
|
|
|
|
#ifdef S4LOG
|
|
static FIELD4INFO log_fields[] =
|
|
{
|
|
{ "ID", 'C', 12,0 },
|
|
{ "LOG1", 'C', 20,0 },
|
|
{ "LOG2", 'C', 20,0 },
|
|
{ 0,0,0,0 },
|
|
} ;
|
|
#endif
|
|
|
|
D4DISPLAY *disp ;
|
|
CODE4 cb;
|
|
DATA4 *co_ptr, *wo_ptr, *re_ptr ;
|
|
DATA4 *log_ptr = 0 ;
|
|
INDEX4 *w1_ptr, *w2_ptr ;
|
|
FIELD4 *command_field, *parm, *work, *result, *log_id, *logic1, *logic2 ;
|
|
char *log_id_ptr = 0 ;
|
|
char seek_str[WORK_WIDTH+1] ;
|
|
int rc ;
|
|
|
|
static int send_com( char *, char *) ;
|
|
static int int_ret( long, int ) ;
|
|
static void ch_base_locked( long,int);
|
|
static int command_sender(void) ;
|
|
static int work_doer(void) ;
|
|
static void d_lock(void) ;
|
|
static void d_seek(void) ;
|
|
static void d_skip(void) ;
|
|
static void d_write(void) ;
|
|
static void d_append(void) ;
|
|
static void d_unlock(void) ;
|
|
static void i_lock(void) ;
|
|
static void d_append_one(void) ;
|
|
static int seek_recs( long ) ;
|
|
static int write_recs( long ) ;
|
|
static int append_recs( long ) ;
|
|
static int skip_recs( long ) ;
|
|
static int result_int( int) ;
|
|
int test_multi( void ) ;
|
|
static int test_with_mem_check( void ) ;
|
|
|
|
#ifdef S4WINDOWS
|
|
/* transfer control */
|
|
static int t4sleep( long dummy )
|
|
{
|
|
if ( PeekMessage( &disp->msg, disp->hWnd, 0, 0, PM_NOREMOVE ) )
|
|
{
|
|
if ( disp->msg.message == 275 ) /* remove the timer messages */
|
|
{
|
|
if ( !GetMessage( &disp->msg, disp->hWnd, 0, 0 ) )
|
|
return 1 ;
|
|
}
|
|
else
|
|
{
|
|
if ( !GetMessage( &disp->msg, disp->hWnd, 0, 0 ) )
|
|
return 1 ;
|
|
TranslateMessage( (LPMSG)&disp->msg ) ;
|
|
if( disp->msg.message == WM_DESTROY )
|
|
return -1 ;
|
|
DispatchMessage( (LPMSG)&disp->msg ) ;
|
|
}
|
|
}
|
|
return 0 ;
|
|
}
|
|
#else
|
|
static int t4sleep(long) ;
|
|
#endif
|
|
|
|
/* Number of Records per Buffer for T4MUL_WO.dbf */
|
|
#define REC_PER_BUF 2L
|
|
|
|
extern void logger( char *, char * ) ;
|
|
|
|
int first = 1 ;
|
|
int in_logger = 0 ;
|
|
|
|
|
|
void logger( char *p1, char *p2 )
|
|
{
|
|
if ( in_logger || log_ptr == 0 )
|
|
return ;
|
|
in_logger = 1 ;
|
|
|
|
if ( d4lock_file( log_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( first )
|
|
{
|
|
first = 0 ;
|
|
if ( d4zap( log_ptr, 1L, d4reccount( log_ptr ) ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
if ( d4append_start(log_ptr, 0) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( log_id_ptr == (char *) 0 )
|
|
f4assign( log_id, "UNKNOWN" ) ;
|
|
else
|
|
f4assign( log_id, log_id_ptr ) ;
|
|
|
|
f4assign( logic1, p1 ) ;
|
|
f4assign( logic2, p2 ) ;
|
|
|
|
if ( d4append( log_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4flush( log_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4unlock( log_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
in_logger = 0 ;
|
|
}
|
|
|
|
#ifdef S4OS2
|
|
extern unsigned far pascal DOSSLEEP ( unsigned long );
|
|
|
|
static int t4sleep( long n_ms )
|
|
{
|
|
DOSSLEEP( (unsigned long) n_ms ) ;
|
|
return 0 ;
|
|
}
|
|
#else
|
|
#ifndef S4WINDOWS
|
|
static int t4sleep( long n_ms )
|
|
{
|
|
while( n_ms-- > 0 ) ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
int test_multi()
|
|
{
|
|
int rc ;
|
|
|
|
#ifdef S4WINDOWS
|
|
cb.lock_attempts = 1 ; /* don't lock up a Window's application */
|
|
#endif
|
|
|
|
cb.open_error = 0 ;
|
|
#ifdef N4OTHER
|
|
cb.auto_open = 0 ;
|
|
#endif
|
|
|
|
co_ptr = d4open( &cb, "T4MUL_CO" ) ;
|
|
if ( co_ptr == 0 )
|
|
{
|
|
if ( cb.error_code == r4no_open )
|
|
{
|
|
d4display_str( disp, " Creating T4MUL_CO . . . ", 1 ) ;
|
|
co_ptr = d4create( &cb, "T4MUL_CO", co_fields, 0 ) ;
|
|
if ( co_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
else
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
command_field = d4field( co_ptr, "COMMAND" ) ;
|
|
parm = d4field( co_ptr, "PARM" ) ;
|
|
|
|
if ( command_field == 0 || parm == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
wo_ptr = d4open( &cb, "T4MUL_WO" ) ;
|
|
if (wo_ptr == 0 )
|
|
{
|
|
if ( cb.error_code == r4no_open )
|
|
{
|
|
d4display_str( disp, " Creating T4MUL_WO . . . ", 1 ) ;
|
|
wo_ptr = d4create( &cb, "T4MUL_WO", wo_fields, 0 ) ;
|
|
if ( wo_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
else
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
work = d4field( wo_ptr, "WORK" ) ;
|
|
if ( work == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
re_ptr = d4open( &cb, "T4MUL_RE" ) ;
|
|
if (re_ptr == 0 )
|
|
{
|
|
if ( cb.error_code == r4no_open )
|
|
{
|
|
re_ptr = d4create( &cb, "T4MUL_RE", result_fields, 0 ) ;
|
|
if ( re_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
d4display_str( disp, " Creating T4MUL_RE . . . ", 1 ) ;
|
|
}
|
|
else
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
result = d4field( re_ptr, "RESULT" ) ;
|
|
if ( result == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
#ifdef S4LOG
|
|
if ( log_ptr = d4open( &cb, "T4MUL_LO" ) == 0 )
|
|
{
|
|
if ( cb.error_code == r4no_open )
|
|
{
|
|
d4display_str( disp, " Creating T4MUL_LO . . . ", 1 ) ;
|
|
log_ptr = d4create( &cb, "T4MUL_LO", log_fields, 0 ) ;
|
|
if ( log_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
else
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
log_id = d4field( log_ptr, "ID" ) ;
|
|
logic1 = d4field( log_ptr, "LOG1" ) ;
|
|
logic2 = d4field( log_ptr, "LOG2" ) ;
|
|
|
|
logger( "First Log", "" ) ;
|
|
|
|
#endif
|
|
|
|
d4display_str( disp, " Databases Open. ", 1 ) ;
|
|
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
if ( (rc = d4lock_file( wo_ptr )) < 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = -1 ;
|
|
#endif
|
|
|
|
if ( rc == r4locked )
|
|
{
|
|
log_id_ptr = "Commander" ;
|
|
d4display_str( disp, " Commander Session. ", 1 ) ;
|
|
|
|
if ( d4zap( co_ptr, 1L, d4reccount( co_ptr ) ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
for (;;)
|
|
{
|
|
if ( d4refresh( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4reccount( re_ptr ) == 0L )
|
|
break ;
|
|
if ( t4sleep( 50 ) < 0 )
|
|
return -1 ;
|
|
}
|
|
for (;;)
|
|
{
|
|
if ( d4refresh( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4reccount( re_ptr ) > 0L )
|
|
break ;
|
|
if ( d4refresh( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4reccount( co_ptr ) == 0L )
|
|
if ( send_com("UNLOCK ALL", "-1" ) )
|
|
return 1 ;
|
|
if ( t4sleep( 50 ) < 0 )
|
|
return -1 ;
|
|
}
|
|
if ( command_sender() )
|
|
return 1 ;
|
|
d4display_str( disp, " Commander Finished. ", 1 ) ;
|
|
}
|
|
else
|
|
{
|
|
log_id_ptr = "Worker " ;
|
|
d4display_str( disp, " Worker Session. ", 1 ) ;
|
|
|
|
if ( d4zap( wo_ptr, 1L, d4reccount( wo_ptr )) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4zap( re_ptr, 1L, d4reccount( re_ptr ) ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if (d4zap( co_ptr, 1L, d4reccount( co_ptr ) ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
cb.safety = 0 ;
|
|
|
|
w1_ptr = i4create( wo_ptr, "T4MUL_W1", wo_tags_one ) ;
|
|
if ( w1_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c: i4create" ) ;
|
|
|
|
w2_ptr = i4create( wo_ptr, "T4MUL_W2", wo_tags_two ) ;
|
|
if ( w2_ptr == 0 )
|
|
e4severe( e4result, "t4mul.c: i4create" ) ;
|
|
|
|
cb.safety = 1 ;
|
|
|
|
if ( d4unlock( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4unlock( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( work_doer() )
|
|
return 1 ;
|
|
d4display_str( disp, " Worker Finished. ", 1 ) ;
|
|
}
|
|
|
|
if ( d4close_all( &cb ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
#ifdef L4LOCK_CHECK
|
|
if ( l4lock_check() != 0 )
|
|
e4severe( e4result, "Not everything was unlocked" ) ;
|
|
#endif
|
|
if ( cb.error_code < 0 )
|
|
e4severe( e4result, "t4mul.c: cb.error_code" ) ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static int send_com( char *com, char *com_parm )
|
|
{
|
|
if ( d4display_quit( disp ) ) return 1 ;
|
|
|
|
d4display_str( disp, " Sending- Command: ", 1 ) ;
|
|
d4display_str( disp, com, 0 ) ;
|
|
d4display_str( disp, " Parm: ", 1 ) ;
|
|
d4display_str( disp, com_parm, 0 ) ;
|
|
d4display_str( disp, " ", 1 ) ;
|
|
|
|
if ( d4lock_file( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4append_start( co_ptr, 0 ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
f4assign( command_field, com ) ;
|
|
f4assign( parm, com_parm ) ;
|
|
if ( d4append( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4flush( co_ptr ) != 0 )
|
|
e4severe( e4result, (char *) 0 ) ;
|
|
if ( d4unlock( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static int int_ret( long rec, int val )
|
|
{
|
|
if ( d4display_quit( disp ) )
|
|
return 1 ;
|
|
|
|
d4display_str( disp, " Getting Return Record . . . ", 1 ) ;
|
|
d4display_num( disp, rec, 0 ) ;
|
|
|
|
if ( d4unlock( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4refresh( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
while ( d4reccount( re_ptr ) < rec )
|
|
{
|
|
if ( t4sleep(50) < 0 )
|
|
return -1 ;
|
|
if ( d4refresh( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
}
|
|
|
|
if ( d4go( re_ptr, (long)rec ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( f4int( result ) != val )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4unlock( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
d4display_str( disp, " Received.", 1 ) ;
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
/* Check the locks
|
|
|
|
Ran on worker data file to determine what locks another station
|
|
has put on the worker data file. This station none on the worker
|
|
data file when this routine is called.
|
|
|
|
rec_cd - That Record Should be Locked
|
|
- If zero, no specific record is locked
|
|
- If the entire file should be is locked, this must be zero
|
|
|
|
file_cd - Neg one and the whole file should be locked.
|
|
- Zero and the reccount byte should be locked.
|
|
- One and nothing is locked except perhaps a record.
|
|
*/
|
|
static void ch_base_locked( long rec_cd, int file_cd )
|
|
{
|
|
int rc ;
|
|
d4display_str( disp, " Checking Database Locks . . .", 1 ) ;
|
|
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
|
|
rc = d4lock_file( wo_ptr ) ;
|
|
if ( rc < 0 )
|
|
e4severe( e4result, "t4mul.c: d4lock_file" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( rc == r4locked )
|
|
{
|
|
if ( rec_cd == 0 && file_cd == 1 )
|
|
e4severe( e4result, "t4mul.c: Lock Error 0" ) ;
|
|
}
|
|
else
|
|
{
|
|
if (rec_cd != 0L || file_cd != 1 )
|
|
e4severe( e4result, "t4mul.c: Lock Error 1" ) ;
|
|
}
|
|
|
|
if ( (rc = d4lock_append( wo_ptr ) ) < 0 )
|
|
e4severe( e4result, "t4mul.c: d4lock_append" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
/* If record count bytes can be locked, 'worker' cannot have
|
|
the whole file locked. In addition, if the record count
|
|
bytes cannot be locked, they better not be unlocked. */
|
|
|
|
if ( rc == 0 && file_cd <= 0 || rc == r4locked && file_cd == 1 )
|
|
e4severe( e4result, "t4mul.c: Lock Error 2" ) ;
|
|
|
|
if ( d4reccount( wo_ptr ) > 0L )
|
|
{
|
|
if ( (rc = d4lock( wo_ptr, 1L)) < 0 )
|
|
e4severe( e4result, "t4mul.c: d4lock" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
/* If record one can be locked, 'worker' cannot have the whole
|
|
file locked. If they cannot be locked, they better not be locked. */
|
|
if ( rc == 0 && (file_cd == -1 || rec_cd == 1L) || rc == r4locked && file_cd != -1 && rec_cd != 1L)
|
|
e4severe( e4result, "t4mul.c: Lock Error 3" ) ;
|
|
}
|
|
|
|
if ( rec_cd > 0L )
|
|
{
|
|
/* If 'worker' has locked the record, we better not be able to lock it. */
|
|
if ( (rc = d4lock( wo_ptr, rec_cd)) < 0 )
|
|
e4severe( e4result, "t4mul.c: d4lock" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( rc == 0 )
|
|
e4severe( e4result, "t4mul: Lock Error 4" ) ;
|
|
}
|
|
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = -1 ;
|
|
#endif
|
|
}
|
|
|
|
|
|
static int command_sender()
|
|
{
|
|
int i ;
|
|
long count, r ;
|
|
|
|
r = 1L ;
|
|
|
|
if ( int_ret(r++, 0 ) ) return 1 ;
|
|
ch_base_locked(0L, 1) ;
|
|
|
|
/* Lock the work database, it will not be unlocked until
|
|
the index files have been created. */
|
|
d4lock_file( wo_ptr ) ;
|
|
|
|
if ( d4opt_suspend( &cb ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
w1_ptr = i4open( wo_ptr, "T4MUL_W1" ) ;
|
|
w2_ptr = i4open( wo_ptr, "T4MUL_W2" ) ;
|
|
if ( w1_ptr == 0 || w2_ptr == 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
d4opt_start( &cb ) ;
|
|
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
/* Lock an array of records */
|
|
if ( send_com("LOCK 1,3,8", "0" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(1L, 1 ) ;
|
|
ch_base_locked(3L, 1 ) ;
|
|
|
|
if ( send_com("LOCK APPEN", "0" ) )
|
|
return 1;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 0) ;
|
|
|
|
if ( send_com("UNLOCK APP", "0" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 1) ;
|
|
|
|
if ( send_com("LOCK FILE", "-1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, -1) ;
|
|
|
|
if ( send_com("UNLOCK FIL", "-1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked( 0L, 1 ) ;
|
|
|
|
if ( send_com("I4LOCK", "" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
/* Check to make sure the index file is locked. */
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
if ( i4lock( w1_ptr ) != (int)r4locked )
|
|
e4severe( e4result, "t4mul: Index Locking" ) ;
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
|
|
if ( send_com("UNLOCK ALL", "-1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 1) ;
|
|
|
|
/* Check to make sure the index file is unlocked. */
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
if ( i4lock( w1_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul: Index Locking" ) ;
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
for ( i=1; i<= 40; i++ )
|
|
{
|
|
if ( send_com("APPEND ONE", "1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, i ) )
|
|
return 1 ;
|
|
|
|
if ( d4refresh( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
count = d4reccount( wo_ptr ) ;
|
|
if ( count != (long) i )
|
|
e4severe( e4result, "t4mul: Count" ) ;
|
|
}
|
|
|
|
if ( send_com("UNLOCK ALL", "0" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 1) ;
|
|
|
|
if ( d4check( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
if ( d4unlock_data( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
|
|
for ( i=1; i<= 40; i++ )
|
|
{
|
|
if ( d4go( wo_ptr, (long) i ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
if ( f4long(work) != (long) i )
|
|
e4severe( e4result, "t4mul: Append Check" ) ;
|
|
}
|
|
if ( d4zap( wo_ptr, 1L, d4reccount( wo_ptr ) ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
if ( send_com("D4APPEND", "20" ) )
|
|
return 1 ;
|
|
append_recs(20L ) ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( d4refresh( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
if ( d4reccount( wo_ptr ) != 40 )
|
|
e4severe( e4result, "t4mul: Wrong Count" ) ;
|
|
|
|
if ( send_com("LOCK APPEN", "0" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 0) ;
|
|
|
|
if ( send_com("D4LOCK", "5" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(5L, 0 ) ;
|
|
|
|
if ( send_com("LOCK APPEN", "0" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(5L, 0) ;
|
|
|
|
if ( send_com("D4UNLOCK", "0" ) ) /* mean unlock records only */
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 0 ) ;
|
|
|
|
if ( send_com("D4LOCK", "2" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(2L, 0 ) ;
|
|
|
|
if ( send_com("D4UNLOCK", "1" ) ) /* mean unlock records only */
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 0 ) ;
|
|
|
|
if ( send_com("D4LOCK", "5" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(5L, 0 ) ;
|
|
|
|
if ( send_com("UNLOCK ALL", "-1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, 1) ;
|
|
|
|
|
|
/* Test Dirty Read. */
|
|
if ( send_com("LOCK FILE", "-1" ) )
|
|
return 1 ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
ch_base_locked(0L, -1) ;
|
|
|
|
cb.read_lock = 0 ;
|
|
if ( d4go( wo_ptr, 5L ) != 0 )
|
|
e4severe( e4result, "t4mul: Dirty Read" ) ;
|
|
cb.read_lock = 1 ;
|
|
if ( f4long(work) != 5L )
|
|
e4severe( e4result, "t4mul: Dirty Read 2" ) ;
|
|
|
|
/* Test Lock Wait. */
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = 1 ;
|
|
#endif
|
|
if ( d4go( wo_ptr, 5L ) != r4locked )
|
|
e4severe( e4result, "t4mul: Lock Wait" ) ;
|
|
#ifndef S4WINDOWS
|
|
cb.lock_attempts = -1 ;
|
|
#endif
|
|
cb.read_lock = 0 ;
|
|
|
|
if ( send_com("D4SKIP", "1" ) )
|
|
return 1 ;
|
|
skip_recs(-1L ) ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( send_com("D4WRITE", "20" ) ) /* Write Records 1 through 4 many times. */
|
|
return 1 ;
|
|
write_recs(-20L ) ; /* Write Records Backwards. */
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( send_com("D4WRITE", "20" ) ) /* Write Records 1 through 4 many times. */
|
|
return 1 ;
|
|
skip_recs(-1L ) ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( send_com("D4SEEK", "20" ) )
|
|
return 1 ;
|
|
skip_recs(-1L ) ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( send_com("D4SEEK", "-20" ) )
|
|
return 1 ;
|
|
write_recs( 20L ) ;
|
|
if ( int_ret(r++, 0 ) )
|
|
return 1 ;
|
|
|
|
if ( d4check( wo_ptr ) < 0 )
|
|
e4severe( e4result, "t4mul: Check 1" ) ;
|
|
|
|
if ( send_com("DONE", "" ) )
|
|
return 1 ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static int seek_recs( long n )
|
|
{
|
|
long i ;
|
|
long on_rec, direc ;
|
|
|
|
direc = 1L ;
|
|
if ( n < 0 )
|
|
{
|
|
direc = -1L ;
|
|
n = -n ;
|
|
}
|
|
|
|
d4display_str( disp, " Seek Number Recs: ", 1 ) ;
|
|
d4display_num( disp, n, 0 ) ;
|
|
d4display_str( disp, " Seeking Record: ", 1 ) ;
|
|
|
|
for ( i = on_rec = 1L; i<= n; i++)
|
|
{
|
|
disp->x = (int) 0 ;
|
|
d4display_str( disp, " Seeking Record: ", 0 ) ;
|
|
d4display_num( disp, on_rec, 0 ) ;
|
|
|
|
c4ltoa45( on_rec, seek_str, (int) WORK_WIDTH ) ;
|
|
seek_str[WORK_WIDTH] = 0 ;
|
|
if ( d4seek( wo_ptr, seek_str) != 0 )
|
|
e4severe( e4result, "t4mul.c: d4seek" ) ;
|
|
|
|
if ( d4recno( wo_ptr ) != on_rec )
|
|
e4severe( e4result, "t4mul: d4seek_double" ) ;
|
|
|
|
on_rec += direc ;
|
|
if ( on_rec < 1L )
|
|
on_rec = d4reccount( wo_ptr ) ;
|
|
if ( on_rec > d4reccount( wo_ptr ))
|
|
on_rec = 1L ;
|
|
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static int write_recs( long n )
|
|
{
|
|
long i ;
|
|
long on_rec, direc ;
|
|
|
|
direc = 1L ;
|
|
if ( n < 0 )
|
|
{
|
|
direc = -1L ;
|
|
n = -n ;
|
|
}
|
|
d4display_str( disp, " ", 1 ) ;
|
|
|
|
for ( on_rec = i=1L; i<= n; on_rec += direc, i++)
|
|
{
|
|
if ( on_rec < 1L ) on_rec = 20L ;
|
|
if ( on_rec > 20L ) on_rec = 1L ;
|
|
|
|
disp->x = (int) 0 ;
|
|
d4display_str( disp, " Iteration: ", 0 ) ;
|
|
d4display_num( disp, i, 0 ) ;
|
|
d4display_str( disp, " Record: ", 0 ) ;
|
|
d4display_num( disp, on_rec, 0 ) ;
|
|
d4display_str( disp, " ", 1 ) ;
|
|
|
|
if ( d4go( wo_ptr, on_rec ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
f4assign_long( work, on_rec ) ;
|
|
if ( d4flush( wo_ptr ) != 0 )
|
|
e4severe( e4result, (char *) 0 ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static void d_append_one()
|
|
{
|
|
d4display_str( disp, "Append One Next", 1 ) ;
|
|
|
|
if ( d4refresh( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
if ( d4append_start( wo_ptr, 0 ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
f4assign_long( work, d4reccount(wo_ptr) + 1L) ;
|
|
if ( d4append( wo_ptr ) < 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
|
|
if ( d4flush( wo_ptr ) != 0 )
|
|
e4severe( e4result, (char *) 0 ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
result_int( (int) d4reccount( wo_ptr ) ) ;
|
|
}
|
|
|
|
|
|
static int append_recs( long n )
|
|
{
|
|
long i ;
|
|
|
|
d4display_str( disp, " Appending Total: ", 1 ) ;
|
|
d4display_num( disp, n, 0 ) ;
|
|
d4display_str( disp, " Appending: ", 1 ) ;
|
|
|
|
for ( i=1L; i<= n; i++ )
|
|
{
|
|
disp->x = (int) 0 ;
|
|
d4display_str( disp, " Appending: ", 0 ) ;
|
|
d4display_num( disp, i, 0 ) ;
|
|
|
|
if ( d4append_blank( wo_ptr ) < 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
|
|
f4assign_long( work, d4recno(wo_ptr) ) ;
|
|
|
|
if ( d4flush( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( t4sleep( 50 ) < 0 )
|
|
return -1 ;
|
|
}
|
|
|
|
if ( d4check( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
if ( d4unlock_data( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
static int skip_recs( long direc )
|
|
{
|
|
d4display_str( disp, " Skipping Direction: ", 1 ) ;
|
|
d4display_num( disp, direc, 0 ) ;
|
|
|
|
if ( d4refresh( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
#ifdef S4WINDOWS
|
|
while ( d4lock_file( wo_ptr ) == r4locked ) /* until free */
|
|
if ( t4sleep(50) < 0 ) return - 1 ;
|
|
#endif
|
|
|
|
if ( direc < 0 )
|
|
{
|
|
direc = -1L ;
|
|
if ( d4bottom( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
}
|
|
else
|
|
{
|
|
direc = 1L ;
|
|
if ( d4top( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
}
|
|
|
|
d4display_str( disp, " Record On: ", 1 ) ;
|
|
for(;;)
|
|
{
|
|
disp->x = (int) 0 ;
|
|
d4display_str( disp, " Record On: ", 0 ) ;
|
|
d4display_num( disp, d4recno( wo_ptr ), 0 ) ;
|
|
|
|
if ( d4skip( wo_ptr, direc ) < 0 )
|
|
if ( !d4bof( wo_ptr ) && !d4eof( wo_ptr ) )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
if ( f4long(work) != d4recno( wo_ptr ) )
|
|
if ( ! d4eof( wo_ptr ) )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
|
|
if ( d4unlock( wo_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4bof( wo_ptr ) || d4eof( wo_ptr ) )
|
|
{
|
|
if ( d4recno( wo_ptr ) != 1L && d4recno( wo_ptr ) != d4reccount( wo_ptr )+1L )
|
|
e4severe( e4result, "t4mul" ) ;
|
|
return 0 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int result_int( int i )
|
|
{
|
|
if ( d4lock_file( re_ptr ) < 0 )
|
|
e4severe( e4result, "t4mul.c " ) ;
|
|
|
|
if ( d4append_start( re_ptr, 0 ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
f4assign_int( result, i ) ;
|
|
|
|
if ( d4append( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
if ( d4flush( re_ptr ) != 0 )
|
|
e4severe( e4result, (char *) 0 ) ;
|
|
if ( d4unlock( re_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
return i ;
|
|
}
|
|
|
|
static void d_lock()
|
|
{
|
|
result_int( d4lock( wo_ptr, f4long(parm) ) ) ;
|
|
}
|
|
|
|
static void d_lock_append()
|
|
{
|
|
result_int( d4lock_append( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_lock_file()
|
|
{
|
|
result_int( d4lock_file( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_lock_138()
|
|
{
|
|
long a[3] ;
|
|
a[0] = 1L ;
|
|
a[1] = 3L ;
|
|
a[2] = 8L ;
|
|
result_int( d4lock_group( wo_ptr, a, 3) ) ;
|
|
}
|
|
|
|
static void d_unlock()
|
|
{
|
|
result_int( d4unlock_records( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_unlock_append()
|
|
{
|
|
result_int( d4unlock_append( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_unlock_all()
|
|
{
|
|
result_int( d4unlock( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_unlock_file()
|
|
{
|
|
result_int( d4unlock_file( wo_ptr ) ) ;
|
|
}
|
|
|
|
static void d_seek()
|
|
{
|
|
result_int( seek_recs( f4long(parm) )) ;
|
|
}
|
|
|
|
static void d_skip()
|
|
{
|
|
result_int( skip_recs( f4long(parm) )) ;
|
|
}
|
|
|
|
static void d_write()
|
|
{
|
|
result_int( write_recs( f4long(parm) )) ;
|
|
}
|
|
|
|
static void d_append()
|
|
{
|
|
result_int( append_recs( f4long(parm) )) ;
|
|
}
|
|
|
|
static void i_lock()
|
|
{
|
|
result_int( i4lock( w1_ptr )) ;
|
|
}
|
|
|
|
typedef struct list_st
|
|
{
|
|
char work[WORK_WIDTH+1] ;
|
|
void (*f)() ;
|
|
} LIST ;
|
|
|
|
|
|
LIST list[] =
|
|
{
|
|
{ "D4LOCK ", d_lock },
|
|
{ "LOCK APPEN", d_lock_append },
|
|
{ "LOCK FILE ", d_lock_file },
|
|
{ "LOCK 1,3,8", d_lock_138 },
|
|
{ "D4UNLOCK ", d_unlock },
|
|
{ "UNLOCK ALL", d_unlock_all },
|
|
{ "UNLOCK FIL", d_unlock_file },
|
|
{ "UNLOCK APP", d_unlock_append },
|
|
{ "D4SEEK ", d_seek },
|
|
{ "D4SKIP ", d_skip },
|
|
{ "D4WRITE ", d_write},
|
|
{ "D4APPEND ", d_append},
|
|
{ "I4LOCK ", i_lock},
|
|
{ "APPEND ONE", d_append_one},
|
|
{ "", 0 },
|
|
} ;
|
|
|
|
|
|
static int work_doer()
|
|
{
|
|
long co_rec ;
|
|
int i ;
|
|
|
|
d4opt_start( &cb ) ;
|
|
d4display_str( disp, " Received Command: ", 1 ) ;
|
|
|
|
for ( co_rec = 1L;;)
|
|
{
|
|
if ( d4display_quit( disp ) )
|
|
return 1 ;
|
|
|
|
/* Get a Command */
|
|
if ( d4refresh( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4reccount( co_ptr ) < co_rec )
|
|
{
|
|
if ( t4sleep( 50 ) < 0 )
|
|
return -1 ;
|
|
continue ;
|
|
}
|
|
|
|
if ( d4go( co_ptr, co_rec++ ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
if ( d4unlock( co_ptr ) != 0 )
|
|
e4severe( e4result, "t4mul.c" ) ;
|
|
|
|
disp->x = (int) 0 ;
|
|
d4display_str( disp, " Received Command: ", 0 ) ;
|
|
d4display_str( disp, f4str(command_field), 1 ) ;
|
|
d4display_str( disp, " Parameter: ", 0 ) ;
|
|
d4display_str( disp, f4str(parm), 1 ) ;
|
|
|
|
for ( i=0;; i++ )
|
|
{
|
|
if ( list[i].work[0] == '\0' )
|
|
{
|
|
if ( memcmp( f4ptr(command_field), "DONE", 4 ) == 0 )
|
|
return 0 ;
|
|
e4severe( e4result, "Unrecognized Command" ) ;
|
|
}
|
|
else
|
|
{
|
|
if ( strcmp( f4str(command_field), list[i].work ) == 0 )
|
|
{
|
|
#ifdef __TURBOC__
|
|
#pragma warn -pro
|
|
#endif
|
|
|
|
(*list[i].f)() ;
|
|
|
|
#ifdef __TURBOC__
|
|
#pragma warn .pro
|
|
#endif
|
|
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int test_with_mem_check()
|
|
{
|
|
d4init( &cb ) ;
|
|
|
|
cb.hWnd = (unsigned) disp->hWnd ;
|
|
#ifdef S4DLL
|
|
cb.hInst = (unsigned) disp->hInst ;
|
|
#endif
|
|
|
|
if ( test_multi() )
|
|
return 1 ;
|
|
|
|
d4init_undo( &cb ) ;
|
|
mem4reset() ;
|
|
|
|
#ifdef S4DEBUG
|
|
mem4check_memory() ;
|
|
|
|
#ifndef S4DLL
|
|
if ( mem4free_check(100) != 0 )
|
|
e4severe( e4result, "t4mul.c: Memory items not freed" ) ;
|
|
#endif
|
|
#endif
|
|
return 0 ;
|
|
}
|
|
|
|
#endif
|
|
|
|
int S4FUNCTION t4test( D4DISPLAY *display )
|
|
{
|
|
#ifdef S4INDEX_OFF
|
|
display->y += 2 ;
|
|
d4display_str( display, "T4MUL: REQUIRES INDEXING (S4INDEX_OFF DEFINED)", 1) ;
|
|
d4display_str( display, "", 1) ;
|
|
return 1 ;
|
|
#else
|
|
d4display_str( display, "T4MUL Test ", 1 ) ;
|
|
d4display_str( display, " ", 1 ) ;
|
|
|
|
if ( test_with_mem_check() )
|
|
e4exit( &cb ) ;
|
|
display->y += 2 ;
|
|
d4display_str( display,"T4MUL: SUCCESS", 1) ;
|
|
d4display_str( display, "", 1) ;
|
|
return 1 ;
|
|
#endif
|
|
}
|