OpenVMS Source Code Demos

demo_lock_dlm_101.bas

1000	%title	"DEMO_LOCK_DLM_101.BAS"
	%ident	"version_101.2"
	!========================================================================================================================
	! Title  : DEMO_LOCK_DLM_xxx.BAS
	! Author : Neil Rieck	(https://neilrieck.net)
	! Created: 00.04.03
	! Purpose: to demonstrate the use of the DISTRIBUTED LOCK MANAGER method to control access to a shared resource
	! Notes  : to see this program in action, run it three or more sessions each one started 2 seconds later in time
	!
	! Ver Who When   What
	! --- --- ------ --------------------------------------------------------------------------------------------------------
	! 100 NSR 000403 1. original work
	!     NSR 050901 2. modified to compile correctly without needing "[.inc]VMS_Externals.inc"
	! 101 NSR 051003 1. changed the $enqw calls to $enq (no wait)
	!		 2. simplified original example but now call $getlki to test the lock status (polling loop)
	!========================================================================================================================
	! calls:	$enq		enqueue		(async)
	!		$enqw		enqueue wait	(sync)
	!		$deq		dequeue
	!		$getlki		get lock info
	!
	! lock modes:	lck$m_nlmode	null
	!		lck$m_crmode	concurrent read		allows shared reading
	!		lck$m_cwmode	concurrent write	allows shared writing
	!		lck$m_prmode	protected read		allows shared read but no writers
	!		lck$m_pwmode	protected write		allows shared read but no other writers (other than self)
	!		lck$m_exmode	exclusive		allows no sharing with others
	!========================================================================================================================
	option type=explicit							! no kid stuff
	!
	%include "starlet"	%from %library "sys$library:basic$starlet"	! system services
        %include "$ssdef"	%from %library "sys$library:basic$starlet"	! ss$
        %include "$lckdef"	%from %library "sys$library:basic$starlet"	! lck$
        %include "$lkidef"	%from %library "sys$library:basic$starlet"	! lki$
	!
	declare long	rc%						,	!						&
		long	loop_counter%		 				!
	!
	!	define stuff to be used during $enq and $deq
	!
	record lock_block_rec				! define a new data structure
		word	lock_condition		,	!						&
			reserved		,	!						&
		long	lock_ident		,	! lock id#					&
		byte	lock_value(16)		 	! (only required with flag: lck$m_valblk)
	end record lock_block_rec		 	!
	declare lock_block_rec lock_block	 	! declare a variable
	!
	!	define stuff to be used in a general purpose item list
	!
        record ItemRec
	    variant
		case
		    group one
			word Buf_Len		! buffer size (in bytes)
			word Code		! desired operation
			long Buf_Addr		! buffer address
			long Rtrn_Len_Addr	! addr of bytes returned
		    end group one
		case
		    group two
			long list_term		! mark end-of-list
		    end group two
	    end variant
        end record
	!
	!	define stuff to be used in testing the status of a queue lock
	!
	record LkiRec				! structure of Lki Record
	    ItemRec ItemVar(9)			! 0 -> 9 items
        end record LkiRec			!
	declare LkiRec	LkiVar			! declare a variable
	!
	!	define stuff to be used in testing the status of a queue lock
	!
	record LockStatusRec			! structure of a lock status record
	    byte	byte0			! LKI$B_STATE_RQMODE
	    byte	byte1			! LKI$B_STATE_GRMODE
	    byte	byte2			! LKI$B_STATE_QUEUE
	end record LockStatusRec		!
	declare LockStatusRec	LockStatus	! declare a variable
	!
	!========================================================================================================================
	!	main
	!========================================================================================================================
	main:
	!
	! SYS$ENQ [efn] ,lkmode ,lksb ,[flags] ,[resnam] ,[parid] ,[astadr] ,[astprm] ,[blkast] ,[acmode] ,[rsdm_id]
	!
	!	<<< request an exclusive lock on a named resource >>>
	!
	print "-i-enq ex"
	rc% = sys$enq(				,! efn:							&
			lck$k_exmode		,! lkmode: exclusive					&
			lock_block		,! lksb:						&
						,! flags:						&
			"NEIL_DEMO_9876"	,! resname: name of the protected resource 		&
			,,,,,,,	)
	print "-e-enq ex rc:",str$(rc%)	if (rc% and 1%) <> 1%
	!
	!	<<< now test our lock status (because we might not have exclusive access) >>>
	!
	loop_counter% = 0							! init counter
	get_lock_status:
	LkiVar::ItemVar(0)::Buf_Len		= 3				! buffer size (in bytes)
	LkiVar::ItemVar(0)::Code		= lki$_state			! desired operation
        LkiVar::ItemVar(0)::Buf_Addr		= loc(LockStatus)		! buffer address
        LkiVar::ItemVar(0)::Rtrn_Len_Addr	= 0				!
        LkiVar::ItemVar(1)::list_term		= 0				! terminate the list
	!
	!	SYS$GETLKI [efn] ,lkidadr ,itmlst [,iosb] [,astadr] [,astprm] [,nullarg]
	!
	rc% = sys$getlki(						&
						,! efn:			&
	    lock_block::lock_ident		,! lkiadr:		&
	    LkiVar::ItemVar(0)::Buf_Len		,! itmlst		&
						,! iosb			&
	    ,,)
	print "-e-getlki rc:",str$(rc%)	if (rc% and 1%) <> 1%
	!
	print "-i-Requested: ";LockStatus::byte0				!
	print "-i-Granted  : ";LockStatus::byte1				!
	print "-i-Queue    : ";LockStatus::byte2				!
	if LockStatus::byte0 <> LockStatus::byte1 then
	    loop_counter% = loop_counter% + 1
	    print "-w- waiting for grant. Count: "+ str$(loop_counter%)
	    sleep 1
	    goto get_lock_status
	end if
	!
	print "-i-starting fake work (15 seconds)"
	sleep 15								! do some work
	print "-i-finished fake work"
	!
	!	remove "our interest" in this resource
	!
	!	SYS$DEQ [lkid] ,[valblk] ,[acmode] ,[flags]
	!
	dequeue:
	print "-i-deq"
	rc% = sys$deq(					&
	    lock_block::lock_ident	,! lkid:	&
					,! valblk:	&
					,! acmode:	&
	    LCK$M_DEQALL		 ! flags:	&
					)
	print "-e-deq rc:",str$(rc%)	if (rc% and 1%) <> 1%
	!
	!	that's all folks
	!
	print "adios..."
	end									!

Back to Home
Neil Rieck
Waterloo, Ontario, Canada.