OpenVMS Source Code Demos

VMS_LOCK_DLM.C

/*===============================================================================================================================
 * title  : VMS_DEMO_LOCK_DLM.C
 * author : Neil Rieck
 * create : 01.01.02 (converted from my Compaq-BASIC version)
 * Purpose: to demonstrate the use of the OpenVMS DISTIRBUTED LOCK MANAGER method to control access to a shared resource
 * Use    : run 2 instances of this program from 2 terminals logged in with the same user id.
 * Notes  : 1. in this demo it is assumed that this process needs exclusive write access to a resource
 *        : 2. other processes waiting for the locked resource will be served in first come - first served order
 *	  : 3. this method can be made to work across a VMS Cluster
 *========================================================================================================================
 * 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
 *========================================================================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <descrip.h>
#include <lckdef.h>

#define FULL_DEMO 0	/* 0=PARTIAL, 1=FULL */
int main ( int argc, char **argv )
{
	unsigned short	rc;				/* return code (from system calls) */

	struct lock_status_block_sturct{		/* define a new data structure */
		unsigned short	lock_condition,
				reserved;
		unsigned long	lock_ident;		/* lock id */
		char		lock_value[16];		/* only required with flag: LCK$M_VALBLK */
	} lock_status_block;

	if ( argc < 2 ){
		fprintf ( stderr,"-e-Missing argument (desired resource name)\n" );
		exit(2);						/* VMS-e- error */
	}

	struct dsc$descriptor_s resource_name;
	resource_name.dsc$w_length	= strlen( argv[1] );
	resource_name.dsc$a_pointer	= argv[1];
	resource_name.dsc$b_class	= DSC$K_CLASS_S;
	resource_name.dsc$b_dtype	= DSC$K_DTYPE_T;

#if FULL_DEMO==1
	/*
	 * SYS$ENQW [efn] ,lkmode ,lksb ,[flags] ,[resnam] ,[parid] ,[astadr] ,[astprm] ,[blkast] ,[acmode] ,[rsdm_id]
	 *
	 *	place a "null" lock (OpenVMS will make an entry in the lock manager if one doesn't exist)
	 */
	printf("-i-enqw null lock\n");
	rc = sys$enqw(	0			,/* efn:						*/
			LCK$K_NLMODE		,/* lkmode: null; just indicates an interest		*/
			&lock_status_block	,/* lksb:						*/
			0			,/* flags:						*/
			&resource_name		,/* resname: name of the protected resource 		*/
			0,0,0,0,0,0,0,0	);
	if ((rc & 1)==1)
	{	printf ("-s-enqw null lock rc:%d\n",rc);
	}else{	printf ("-e-enqw null lock rc:%d\n",rc);
	}

	/*
	 *	convert our "null" lock to a "protected write" lock
	 */
	printf("-i-enqw protected write\n");
	rc = sys$enqw(	0			,/* efn:						*/
			LCK$K_PWMODE		,/* lkmode: protected write				*/
			&lock_status_block	,/* lksb:						*/
			LCK$M_CONVERT		,/* flags:						*/
			&resource_name		,/* resname: name of the protected resource 		*/
			0,0,0,0,0,0,0,0 );
	if ((rc & 1)==1)
	{	printf("-s-enqw protected write rc:%d\n",rc);
	}else{	printf("-e-enqw protected write rc:%d\n",rc);
	}
#endif
	/*
	 *	convert our "protected write" lock to an "exclusive" lock
	 */
	printf("-i-enqw exclusive\n");
	rc = sys$enqw(	0			,/* efn:						*/
			LCK$K_EXMODE		,/* lkmode: exclusive					*/
			&lock_status_block	,/* lksb:						*/
			LCK$M_CONVERT		,/* flags:						*/
			&resource_name		,/* resname: name of the protected resource 		*/
			0,0,0,0,0,0,0,0 );
	if ((rc & 1)==1)
	{	printf("-s-enqw exclusive rc:%d\n",rc);
	}else{	printf("-e-enqw exclusive rc:%d\n",rc);
	}

	printf("starting some work (will just wait 10 seconds)\n");
	sleep(10);
	printf("finished work\n");

#if FULL_DEMO==1
	/*
	 *	convert our "exclusive" lock back to a "null" lock
	 */
	printf("-i-enqw null\n");
	rc = sys$enqw(	0			,/* efn:						*/
			LCK$K_NLMODE		,/* lkmode: null					*/
			&lock_status_block	,/* lksb:						*/
			0			,/* flags:						*/
			&resource_name		,/* resname: name of the protected resource 		*/
			0,0,0,0,0,0,0,0	);
	if ((rc & 1)==1)
	{	printf( "-s-enqw null rc:%d\n",rc);
	}else{	printf( "-e-enqw null rc:%d\n",rc);
	}
#endif
	/*
	 *	remove "our intrest" in this resource
	 *
	 *	SYS$DEQ [lkid] ,[valblk] ,[acmode] ,[flags]
	 */
	printf("-i-deq all\n");
	rc = sys$deq(	0		,/* lkid:	*/
			0		,/* valblk:	*/
			0		,/* acmode:	*/
			LCK$M_DEQALL	 /* flags:	*/
			);
	if ((rc & 1)==1)
	{	printf("-s-deq all rc:%d\n",rc);
	}else{	printf("-e-deq all rc:%d\n",rc);
	}
	exit(1);							/* vms-s-success */
}

Back to Home
Neil Rieck
Waterloo, Ontario, Canada.