/* Copyright 2003-2023 James F. Duff */
/* License and disclaimer: http://www.eight-cubed.com/disclaimer.html */

#define __NEW_STARLET 1

#include <stdio.h>
#include <stdlib.h>
#include <ssdef.h>
#include <stsdef.h>
#include <lib$routines.h>
#include <starlet.h>

#include "errchk.h"

/*
** Weird, the version of starlet.h I have on OpenVMS 8.2 does not seem to have
** a prototype for sys$clrast ().  Define one if not already defined.
*/
#ifndef sys$clrast
#define sys$clrast SYS$CLRAST
int sys$clrast (void);
#endif


/******************************************************************************/
static void ast_two (int efn) {

static int r0_status;

    (void)printf ("In ast_two\n");

    /*
    ** Set the event flag.
    */
    r0_status = sys$setef (efn);
    errchk_sig (r0_status);

    (void)printf ("Out ast_two\n");
}


/******************************************************************************/
static void ast_one (void) {

static int r0_status;

    /*
    ** Show where we are.
    */
    (void)printf ("In ast_one\n");

    /*
    ** Queue another user mode AST.  In normal circumstances, ast_two would not
    ** be delivered until after we return from ast_one.  However...
    */
    r0_status = sys$dclast (ast_two, 2, 0);
    errchk_sig (r0_status);

    /*
    ** Clear an event flag.
    */
    r0_status = sys$clref (2);
    errchk_sig (r0_status);

    /*
    ** Say that we are no longer interested in AST synchonization (!!!)
    */
    sys$clrast ();

    /*
    ** Wait for the event flag to set.  Note that under normal circumstances
    ** this would be a dumb idea.
    */
    r0_status = sys$waitfr (2);
    errchk_sig (r0_status);

    /*
    ** Say where we are.
    */
    (void)printf ("Out ast_one\n");
}


/******************************************************************************/
int main (void) {
/*
** Danger, Will Robinson!  This code employs SYS$CLRAST, which says to the
** operating system "I am no longer executing as an AST".
**
** In the normal course of events (ie, if you don't call SYS$CLRAST) the
** operating system queues ASTs of the same mode so that they occur one after
** the other.  This is an inherent synchronization method within the operating
** system, and usually should not be thwarted.  (Of course, inner mode
** ASTs can interrupt outer mode ones: that what it's all about.  But under
** normal circumstances, a user mode AST cannot interrupt a user mode AST
** already executing.  SYS$CLRAST allows this to happen.  HP strongly
** discourages the use of this system service, as it's *definately* easy
** to shoot yourself if the foot by calling it).
*/

static int r0_status;

    /*
    ** Get a user mode AST running...
    */
    r0_status = sys$dclast (ast_one, 0, 0);
    errchk_sig (r0_status);
}

Back to the master examples list.