Newsgroups: vmsnet.internals
Path: news.mitre.org!blanket.mitre.org!news.tufts.edu!cam-news-feed5.bbnplanet.com!cam-news-hub1.bbnplanet.com!news.bbnplanet.com!news.maxwell.syr.edu!news-peer.gip.net!news.gsl.net!gip.net!news.new-york.net!news.mag.aramark.com!news
From: Linwood Ferguson <Ferguson@mag.aramark.com>
Subject: Re: 'durable' Lock after image termination
NNTP-Posting-Host: pc-ferguson.mag.aramark.com
X-Mailer: Mozilla 3.01 (WinNT; I)
Content-Type: text/plain; charset=us-ascii
References: <009BDC7B.4C98D367.25@spotimage.fr>
Sender: news@news.mag.aramark.com (Network News)
Mime-Version: 1.0
Organization: ARAMARK Mag & BooK Services
Date: Wed, 26 Nov 1997 22:52:54 GMT
Message-ID: <347CA846.2A7B@mag.aramark.com>
Content-Transfer-Encoding: 7bit
Lines: 323

Old C programs below that will do what you want, change as needed for
wait/nowait.  Use with caution, bugs in it can crash things since it
runs with priv (and to work from non-priv users needs to be installed
with privs).

Hope it doesn't wrap too badly coming through news.

-- 
Linwood Ferguson                 e-mail: ferguson@mag.aramark.com
Mgr. Software Engineering        Voice:  (US) 540/967-0087
ARAMARK Mag & Book Services

System Manager wrote:
> 
> hello,
> 
> is it possible to do that:
> 
> $ run lock_some_resource
> 
> .
> . <resource locked using the lock manager>
> .
> 
> $ run unlock_the_resource
> 
> with the ressources automatically freed if the
> process dies without unlocking it.
> 
> thanks in advance
> Pierre Bru.


----

/*
**++
**  BRIEF DESCRIPTION:
**
**      Lock resource from DCL in Supervisor mode
**
**  FUNCTIONAL DESCRIPTION:
**
**      Invoke routines to lock resource (provided on command line),
**      and wait until it is available.  The lock value is returned
**      in the CLI symbol LOCK_LOCK.  This should be used if the
**      UNLOCK program is to be used (though process termination
**      is sufficient to unlock the resource).
**
**      This program should be used to provide synchronization of
**      command procedures, namely to prevent critical sections of
**      code (or whole jobs) from running concurrently.  For example,
**      if job X (in command procedure X.COM) should never have two
**      versions of itself running at once, each should call this
**      program at the beginning.  The other will wait, stalled at
**      the LOCK statement.  Note that the other WILL run when the
**      first has terminated.
**
**      Generally, this routine should be called with a unique
**      resource name concatenated with a dataset name, e.g.:
**
**          LOCK  'f$trnlnm("sys_unitcode")'ENDOFMONTH
**          
**  CALLING PROTOCOL:
**
**      LOCK :== $SYS_PROGRAMS:LOCK    ! normally defined at login
**      LOCK resource
**
**  FACILITY: MECHANISMS
**
**  FORMAL PARAMETERS:
**
**      Foreign command line = resource name
**
**  RETURN VALUE:
**
**      Last status from calls, odd=successful
**
**  IMPLICIT INPUTS:
**
**      Must be run with CMEXEC and SYSLCK
**
**  IMPLICIT OUTPUTS AND SIDE EFFECTS:
**
**      Defines CLI symbol LOCK_LOCK
**--
*/
main (int argc, char *argv[])
  { int i;
    long int ret;
#pragma nostandard
    long int ast_args[4] = {3,(long int)super_routine,0,PSL$C_SUPER};
#pragma standard

    /* Get resource name from command line */
    
    if (argc<=1) { printf("%LOCK-E-NORES, No resource on command
line\n"); return 2;}
    for (i=0; i<31; i++) resource[i] =
(i<strlen(argv[1])?toupper(argv[1][i]):' ');

    /* Start exec mode routine which requests routine to run in
supervisor  */
    /* mode which actually does the
work.                                   */

    ret = sys$cmexec (sys$dclast,ast_args);  if ((ret&1)!=1) return ret;
    while (lock_status==0) sys$hiber;

    /* AST has run at this point, define symbol and
exit                    */

    if ((lock_status&1)!=1) lib$set_symbol(&lock_lock_dx,&blank_dx,0);
    else lib$set_symbol(&lock_lock_dx,&lock_hex_dx,0);
    return lock_status;
  }
 
REAL:[SYS.SOURCE]UNLOCK.C;2
 
/*
**++
**  MODULE DESCRIPTION:
**
**      UNLOCK - Unlock resource from DCL level (complement of LOCK)
**
**      (see documentation on main routine below)
**      
**  AUTHOR:
**
**      Linwood Ferguson
**
**  CREATION DATE:  18-Nov-1990
**
**  MODIFICATION HISTORY:
**  06-Jan-1996   Linwood        Include stdio.h & string.h for DEC C
(SY_2042)
**                               Correct datatype, correct bug in
-nolckid message.
**
**--
*/
#include <lkidef.h>
#include <starlet.h>
#include <psldef.h>
#include <lckdef.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

long int unlock_status = 0;           /* Returned status from
$DEQ          */
char lockid_hex[32];                  /* Lockid name string (not zero
term) */
long int lock_id;                     /* Binary lock
id                     */







































/*
**++
**  BRIEF DESCRIPTION:
**
**      SUPER_ROUTINE - Supervisor mode AST routine to dequeue lock
**
**  FUNCTIONAL DESCRIPTION:
**
**      This routine is run in AST mode in Supervisor mode and does the
actual
**      lock $DEQ.  This is necessary because both the resource name and
the
**      lock are in Supervisor mode.
**
**      The status is returned to the main routine through the global
variable
**      unlock_status since this is running as an AST.
**
**  CALLING PROTOCOL:
**
**      super_routine()
**
**  FACILITY: INTERNAL
**
**  FORMAL PARAMETERS:
**
**      None
**
**  RETURN VALUE:
**
**      Return from SYS$WAKE (actually irrelevant because this is an
AST)
**
**      (Note: The $DEQ return value is written into unlock_status)
**
**  IMPLICIT INPUTS:
**
**      Must be in supervisor mode when executed
**
**  IMPLICIT OUTPUTS AND SIDE EFFECTS:
**
**      None
**
**--
*/
static long int super_routine (void)
  { unlock_status=sys$deq(lock_id,0,PSL$C_SUPER,0);
    return sys$wake();          /* Have to wake outer process */
  }





/*
**++
**  BRIEF DESCRIPTION:
**
**      UNLOCK resource locked by LOCK
**
**  FUNCTIONAL DESCRIPTION:
**
**      Invoke routines to unlock resource (provided on command line).
**
**      This is the complement to LOCK, which locks a resource in
**      supervisor mode from DCL, so that it can remain through
**      several image activations.  See the LOCK.C documentation.
**
**  CALLING PROTOCOL:
**
**      UNLOCK :== $SYS_PROGRAMS:UNLOCK     ! normally provided at login
**      UNLOCK lockid
**
**      Commonly, the lock id will be in the CLI symbol LOCK_LOCK
**      and the command will be
**
**          UNLOCK 'lock_lock'
**
**      Note that the LOCK_LOCK symbol is a LOCAL symbol, so it must
**      be used at or below the level that LOCK is used.
**      
**  FACILITY: MECHANISMS
**
**  FORMAL PARAMETERS:
**
**      Foreign command line = lock ID
**
**  RETURN VALUE:
**
**      Last status from calls, odd=successful
**
**  IMPLICIT INPUTS:
**
**      Must be run with CMEXEC and SYSLCK
**
**  IMPLICIT OUTPUTS AND SIDE EFFECTS:
**
**      None
**--
*/
main (int argc, char *argv[])
  { int i;
    long int ret;
#pragma nostandard
    long int ast_args[4] = {3,(long int)super_routine,0,PSL$C_SUPER};
#pragma standard
    
    /* Get lock ID from command line */
    
    if (argc<=1) { printf("%%UNLOCK-E-NOLCKID, No lock id on command
line\n"); return 2;}
    for (i=0; i<31; i++) lockid_hex[i] =
(i<strlen(argv[1])?toupper(argv[1][i]):' ');
    lockid_hex[31]='0'; lock_id = strtol(lockid_hex,NULL,16);

    /* Start exec mode routine which requests routine to run in
supervisor  */
    /* mode which actually does the
work.                                   */

    ret = sys$cmexec (sys$dclast,ast_args);  if ((ret&1)!=1) return ret;
    while (unlock_status==0) sys$hiber;

    /* AST has run at this point,
exit                                      */

    return unlock_status;
  }
