[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference vaxaxp::vmsnotes

Title:VAX and Alpha VMS
Notice:This is a new VMSnotes, please read note 2.1
Moderator:VAXAXP::BERNARDO
Created:Wed Jan 22 1997
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:703
Total number of notes:3722

294.0. "Question about Perm. MAILBOX" by HGRD01::HOMANSANG (Keith Ho, ISE HK @HGO) Fri Mar 07 1997 01:21

    I have a problem about MAILBOX.
    
    A permanent MAILBOX was created and when I did $SHOW DEV/FULL, it
    showed  that the mailbox had a default message size of 1024.  (1024 is
    in fact the max size specificed when creating the MAILBOX.   Then a
    logical pointing to that MAILBOX was inserted into system logical
    table.
    
    When I tried to write to the mailbox, I first called the CREMBX like:
    
         sys$crembx(1,&channel,0,0,0,0,&mbx_logical,0,0);
    or   sys$crembx(1,&channel,1024,0,0,0,&mbx_logical,0,0);
    or   sys$crembx(1,&channel,1024,4*1024,0,0,&mbx_logical,0,0);
    (All this will return SUCCESS.)
    
    and then write to the mailbox using
    
         sys$qiow(0,channel,IO$_WRITEVBLK,&iosb,0,0,message,1024,0,0,0,0);
    
    This call will return error code 412 which is "mailbox is too small for
    request".
    
    However, if I used "sys$assign(&mbx_logical,&channel)" to assign the
    channel (ie. not using CREMBX), the qiow write (as well as other read
    operations) run successfully.
    
    So, is there anyone who can shed some light on this.   What is the
    difference in CREMBX and ASSIGN?
    
    Thank you!
    
    - Keith.
T.RTitleUserPersonal
Name
DateLines
294.1Neglected To Account For Mailbox OverheadXDELTA::HOFFMANSteve, OpenVMS EngineeringFri Mar 07 1997 11:4830
   In the failing case, you're neglecting to include room for the overhead
   in the requested mailbox size and buffer quota -- I'd round up somewhat.

   In the successful case, you can check the SYSGEN parameters that are
   the defaults when no maximum message quota and no buffer quota is
   specified, and I strongly suspect you will see these are larger than
   your specified (and failing) 1024 and 8192 values.

   I do not know that the exact size of the overhead was ever officially
   defined -- I suspect not, given the potentially volatile nature of the
   overhead.  (The overhead -- specifically the mailbox UCB and the logical
   name (if one was specified) -- is, however, clearly documented.)

   I do not recommend depending on the default values from SYSGEN, as
   these values can be highly site-specific.  They can be too small, or
   surprisingly, too large.  (In the latter case, I've seen large values
   exceed the available process quotas, causing an unexepected failure.)

   Permanent mailboxes are also often misused -- some folks use these
   to make the mailbox "globally" visible, when the use of a temporary
   mailbox and either a temporarily redefined temporary mailbox logical
   name table or -- my preference -- a user-created logical name in the
   approproate logical name table can be used.  Temporary mailbox object
   protections can easily be configured to allow general system-wide
   access...  And temporary mailboxes automatically clean themselves
   up, where permanenant mailboxes require an explicit cleanup.  Most
   applications have a mailbox reader running at all times, hence most
   applications can use temporary mailboxes...

294.2AUSS::GARSONDECcharity Program OfficeFri Mar 07 1997 17:468
    re .0
    
    I can't explain the observed behaviour but would point out that $CREMBX
    may or may not create a new mailbox. Hence to fully diagnose the
    problem, a start would be to see the code that creates the permanent
    mailbox and to know what $CREMBX calls are creating mailboxes and which
    ones are "reusing" an existing mailbox. A small, complete demo program
    would help and a statement of VMS version and arch.
294.3More information.HGRD01::HOMANSANGKeith Ho, ISE HK @HGOSun Mar 09 1997 22:0734
    More information:
    
    It's on OpenVMS VAX V6.1.
    
    The mailbox is created using 
    
      sys$crembx(1,&channel,1024,4*1024,0,0,&logname,0,0)  
    
    (The actual crembx code is in MACRO and I just translated it into C as
     I don't have the exact code right now.  It is at the customer site.)
    
    What I'm doing is that the customer site has a permanent mailbox
    created for their inter-process communication.  I wrote a small program
    to insert messages into the mailbox for testing process.   When I used
    $crembx, it has the problem in .0 while it's running fine when I used
    $assign.
    
    The code at customer's site will always use $assign to open the mailbox
    for write operation.   Perhaps they hit the same problem and used
    $assign instead.   However, I have no way to verify this as no one at
    the customer's site can answer most of my questions, including this. 
    You know, this site is a typical customer site where turnover rate is very
    high and virtually no documentation of any kind is available. 
    Furthermore, the code is really in a mess.
    
    For the problem in .0, I just want to know more as I can use $assign
    without any problem at all.
    
    I will try to create a small demo program, if possible.  However, I
    cannot exactly emulate the customer's code as they were too
    complicated.  Therefore, I may not able to reproduce the problem using my
    code.   FYI, the customer are using BASIC, C, MACRO, COBOL, ACMS, TDMS,
    RDB, Datatrieve etc.  For mailbox operations I had seen, they were written
    in BASIC, C and MACRO.
294.4Pad The Mailbox Size and Buffer Quota...XDELTA::HOFFMANSteve, OpenVMS EngineeringMon Mar 10 1997 11:26295
:    The mailbox is created using 
:    
:      sys$crembx(1,&channel,1024,4*1024,0,0,&logname,0,0)  
:    
:    (The actual crembx code is in MACRO and I just translated it into C as
:     I don't have the exact code right now.  It is at the customer site.)

   You need a larger message size, and a larger buffered quota value.
   Change the mailbox creation call to:

      #define MAX_MBX_MSG_SIZE		1024
      #define MAX_MBX_MSG_COUNT		4
      #define MBX_OVERHEAD		1024
      sys$crembx(1,&channel,MAX_MBX_MSG_SIZE+MBX_OVERHEAD,
	MAX_MBX_MSG_COUNT*(MAX_MBX_MSG_SIZE+MBX_OVERHEAD),
	0,0,&logname,0,0)  
    
:    What I'm doing is that the customer site has a permanent mailbox
:    created for their inter-process communication.  I wrote a small program
:    to insert messages into the mailbox for testing process.   When I used
:    $crembx, it has the problem in .0 while it's running fine when I used
:    $assign.

   You do not likely need a permanent mailbox for this, and I'd avoid
   using a permanent mailbox for this -- you will likely always have a
   "reader" process associated with each mailbox, hence you can use
   temporary mailboxes and -- if necessary -- group or system logical
   names to reference the name(s) of the mailbox(es) in use.

   Assumed need for a permanent mailbox is a common mistake.  Other
   than the benefit of the default visibility of the mailbox logical
   name, there are few advantages.  The (major) liability is the need
   to explicitly "clean up" any permanent mailboxes that are no longer
   needed.  (And one can potentially have message(s) left dangling in
   these mailboxes.)

   The other classic mailbox programming design commonly made among
   those new to mailboxes is the use of a single mailbox for
   bi-directional traffic.  Use two uni-directional mailboxes -- it
   makes the communications protocol far easier to design, and (often)
   far more reliable...
    
:    I will try to create a small demo program, if possible.  However, I
:    cannot exactly emulate the customer's code as they were too
:    complicated.  Therefore, I may not able to reproduce the problem using my
:    code.   FYI, the customer are using BASIC, C, MACRO, COBOL, ACMS, TDMS,
:    RDB, Datatrieve etc.  For mailbox operations I had seen, they were written
:    in BASIC, C and MACRO.

   The mailbox message size is too close to the actual message size.

   Here is an example program:


#module	MBXDEMO "SRH X1.0-000"
#pragma builtins

/*
** COPYRIGHT (c) 1993 BY
** DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS.
** ALL RIGHTS RESERVED.
**
** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
** ONLY  IN  ACCORDANCE  OF  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR  ANY  OTHER
** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
** OTHER PERSON.  NO TITLE TO AND  OWNERSHIP OF THE  SOFTWARE IS  HEREBY
** TRANSFERRED.
**
** THE INFORMATION IN THIS SOFTWARE IS  SUBJECT TO CHANGE WITHOUT NOTICE
** AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
** CORPORATION.
**
** DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE  OR  RELIABILITY OF ITS
** SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
*/

/*
**++
**  Facility:
**
**	Examples
**
**  Version: V1.0
**
**  Abstract:
**
**	Shows some master-slave mailbox operations from C
**
**  Author:
**	Brian Breathnach
**
**  Creation Date:  ??-Mar-1993?
**
**  Modification History:
**	11-Mar-1993 Steve Hoffman
**	    Heavily modified and reorganized, debugged
**
**--
*/

#include <ctype.h>
#include <descrip.h>
#include <dvidef.h>
#include <lib$routines.h>
#include <rms.h>
#include <prcdef.h>
#include <iodef.h>
#include <ssdef.h>
#include <starlet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stsdef.h>

typedef unsigned short int ushort_t;
typedef unsigned long int ulong_t;
typedef unsigned char uchar_t;
typedef struct
    {
    ushort_t cond_value;
    ushort_t count;
    ulong_t info;
    } mbxiosb_t;
typedef struct itemlist_3
    {
    ushort_t itmlen, itmcod;
    uchar_t *itmbuf;
    ushort_t *itmrla;
    } itemlist_3_t;
#define MAXDEVNAMLEN	16
#define MAXMBXMSG	1024
#define MAXMBXBUF       4096
#define MBXNAM		"MBXDEMOMBX"
#define MASTERNAM	"MBXDEMO_MASTER"
#define SLAVENAM	"MBXDEMO_SLAVE"
#define MASTEREXE	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_MASTER.EXE"
#define SLAVEEXE	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_SLAVE.EXE"
#define MASTERLOG	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_MASTER.LOG"
#define SLAVELOG	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_SLAVE.LOG"
#define MASTERDAT	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_MASTER.DAT"
#define SLAVEDAT	"_XDELTA$DKB300:[HOFFMAN.EXAMPLES]MBXDEMO_SLAVE.DAT"

#ifdef MASTER
main()
    {
    mbxiosb_t iosb;
    uchar_t devnam_b[MAXDEVNAMLEN];
    ulong_t pid;
    ulong_t status;
    ushort_t channel;
    ushort_t ret_len;
    FILE fHandle;
    struct dsc$descriptor devnam_d =
	{
	MAXDEVNAMLEN, 0, 0, devnam_b
	};
    itemlist_3_t getdvi_il[2] =
        {
        MAXDEVNAMLEN, DVI$_FULLDEVNAM, devnam_b, &devnam_d.dsc$w_length,
        0, 0, 0, 0
        };
    uchar_t *datfil_b = SLAVEDAT;
    $DESCRIPTOR( mbxnam_d,  MBXNAM );
    $DESCRIPTOR( nla0_d,    "NLA0:");
    $DESCRIPTOR( imgfnm_d,  SLAVEEXE );
    $DESCRIPTOR( logfnm_d,  SLAVELOG );
    $DESCRIPTOR( prcnam_d,  SLAVENAM );


    /*
    **	Write the selection parameters out to a file.
    **	First, open the file.
    */
    fHandle = fopen(datfil_b, "w");
    if (fHandle == 0)
	return SS$_BADPARAM;

    /*
    **	Write out some details to a file.
    */
    fprintf(fHandle, "Program: %s\n", MASTERNAM );
    fprintf(fHandle, "Time1: %s\n", "01-Jan-1993");
    fprintf(fHandle, "Time2: %s\n", "31-Jan-1993");

    /*
    **	Close the selection parameter file.
    */
    fclose(fHandle);


    /*
    **	Create a mailbox to enable communication with the detached process.
    */
    status = sys$crembx(0, &channel, MAXMBXMSG, MAXMBXBUF,
	0, 0, &mbxnam_d, 0);
    if (!$VMS_STATUS_SUCCESS(status))
	return status;
    status = sys$getdviw( 0, channel, 0, getdvi_il, 0, 0, 0, 0 );
    if (!$VMS_STATUS_SUCCESS( status ))
        return status;

    /*
    **	Create a detached process running image imgfnm_d...
    **
    **	Can be enabled or disabled under the debugger -- deposit a
    **	zero/non-zero value here as required.  (Note that the detached
    **	process should *not* be linked with DEBUG, as the debugger
    **	has no way of obtaining reasonable input in the detached
    **	process... Other than eating commands from the input mbx.)
    */
    status = 0;
    if (status == 0)
	{
	status = sys$creprc(
	    &pid,	    /* PIDADR */
	    &imgfnm_d,	    /* IMGDSC */
	    &devnam_d,	    /* Input */
	    &logfnm_d,	    /* Output */
	    &nla0_d,	    /* error */
	    0,		    /* prvadr */
	    0,		    /* quota */
	    &prcnam_d,	    /* PRNDSC */
	    4, 0, 0,	    /* Baspri, Uic, TrmMbxUnt */
	    PRC$M_DETACH ); /* Stsflg */
	if ( !$VMS_STATUS_SUCCESS(status))
	    return status;
	printf("created proces PID 0x0%x\n",pid);
	}
    /*
    **	Store the name of the parameter file in the message to go into the
    **	mailbox.
    */
    status = sys$qio( 0,
	channel,
	IO$_WRITEVBLK,
	&iosb,
	0, 0, 
	datfil_b, strlen( datfil_b ), 0, 0, 0, 0);
    if (!$VMS_STATUS_SUCCESS(status))
	return status;
    status = sys$synch( 0, &iosb );
    if (!$VMS_STATUS_SUCCESS(status))
	return status;
    if (!$VMS_STATUS_SUCCESS(iosb.cond_value))
	return iosb.cond_value;

    return SS$_NORMAL;
    }
#endif

#ifdef SLAVE
main()
    {
    mbxiosb_t iosb;
    ushort_t channel;
    $DESCRIPTOR( sysinp_d, "SYS$INPUT");
    uchar_t input_b[NAM$C_MAXRSS];
    ulong_t status;

    printf("MBXDEMO detached/slave process starting!\n");

    /*	  
    **	Get a pointer to where the selection parameters are.  Assign
    **	a channel to the SYS$INPUT device -- which is assumed to be
    **	a mail box device -- and read the input from the mailbox.)
    */	  
    status = sys$assign( &sysinp_d, &channel, 0, 0, 0 );
    if (!$VMS_STATUS_SUCCESS(status))
        return status;

    /*
    **	Read from the input device -- the mailbox.
    */
    status = sys$qio(0,
		      channel,
		      IO$_READVBLK,
		      &iosb,
		      0,
		      0,
		      input_b, NAM$C_MAXRSS, 0, 0, 0, 0);
    if (!$VMS_STATUS_SUCCESS(status))
        return status;
    status = sys$synch( 0, &iosb );
    if (!$VMS_STATUS_SUCCESS(status))
        return status;
    if (!$VMS_STATUS_SUCCESS(iosb.cond_value))
         return iosb.cond_value;

    printf("%*s\n", iosb.count, input_b );
    printf("Done!\n");

    return SS$_NORMAL;
    }
#endif
294.5Thanks for the info.HGRD01::HOMANSANGKeith Ho, ISE HK @HGOSun Mar 16 1997 23:0810
    re:.1,.2, .4   Thank you for your information.
    
    I will recommend the customer to change the code (or at least the
    message size during crembx) but I don't think that they will do as the
    current mechanism (crembx + assign) is working fine.  
    
    You know, most customers are reluctant to modify such a complicated
    application without seeing any added values.
    
    -- Keith.