Depending on the exact execution environment, you might be able to count on
jobstep cleanup to CLOSE the DCB. Does not work well if, for instance, the
storage containing the DCB gets freed before end-of-step cleanup gets
control.

It could be considered sloppy programming -- OPENing a DCB with no
corresponding CLOSE -- but you might consider that it was a good tradeoff
versus e.g. 1900 OPENs and CLOSEs.

Charles


-----Original Message-----
From: IBM Mainframe Assembler List [mailto:[email protected]]
On Behalf Of Mike Hochee
Sent: Wednesday, July 10, 2019 2:44 PM
To: [email protected]
Subject: Re: Probably dumb assembler question

Hi Phil, 

Interesting question.   

My approach would be to not answer it at all, if possible. (although I would
like to understand the underlying cause of the 878)  If your execution
requirements/context accommodate, just obtain the storage and open the DCB
on the first invocation, especially if you expect any volume, and leave it
in place until termination time.  On every invocation you would first check
to ensure that you have storage addr for the DCB and the DCB is open, and
then just PUT and return. For good housekeeping you would want a termination
invocation of some kind which closes the DCB and releases the storage.    

HTH, 
Mike 
-----Original Message-----
From: IBM Mainframe Assembler List [mailto:[email protected]]
On Behalf Of Charles Mills
Sent: Wednesday, July 10, 2019 5:12 PM
To: [email protected]
Subject: Re: Probably dumb assembler question

Try FREEPOOL XDCB before the CLOSE.

Or ... a DCBE with RMODE31=BUFF will both do the FREEPOOL automatically and
get the buffers up above the line, where there is more storage.

Charles


-----Original Message-----
From: IBM Mainframe Assembler List [mailto:[email protected]]
On Behalf Of Phil Smith III
Sent: Wednesday, July 10, 2019 1:48 PM
To: [email protected]
Subject: Probably dumb assembler question

Before I try to make the code below runnable as a standalone program, maybe
someone can suggest what's going on here. I have a program (an API) that may
write to SYSPRINT (if there's an error, and it hasn't been passed a buffer
to return the error message to the caller) using the following sequence.
Essentially it's just doing an OPEN, PUT, CLOSE. And that works as expected.

 

BUT it seems to eat storage. That is, if I run a program that calls the API
repeatedly and invalidly, it writes the errors to SYSPRINT, but gets an S878
reason code 10 after 1900-odd iterations. I've tinkered, commenting out the
PUT: no change. So it's not the actual PUT that's irritating it. If I
comment out the CLOSE, it gets the S878 after fewer iterations, which sort
of makes sense: it's leaving the file open. But why is it running out at
all? The DD is just SYSPRINT DD SYSOUT=*, and REGION=0K. I feel like I'm
missing something basic and obvious here (not the first time).

 

Any suggestions gratefully accepted!

 

 

* Message is in WORKMSG on arrival here
         STORAGE OBTAIN,LENGTH=XDCBL,LOC=BELOW  Get 24-bit DCB buffer
         LR    R4,R1         Move pointer to our 24-bit DCB
         MVC   0(XDCBL,R4),XDCB  Copy the DCB down below the line
         MVC   WORKDWRD(XOPENL),XOPEN  Copy the OPEN macro model
         OPEN  ((4),(OUTPUT)),MODE=31,MF=(E,WORKDWRD)  Open for write
         LTR   R15,R15       Did that work??
         JNZ   WRITTEN       No, skip write, release DCB buffer
         PUT   (4),WORKMSG   Write the message
         MVC   WORKDWRD(XCLOSEL),XCLOSE  Copy in CLOSE template
         CLOSE ((4)),MODE=31,MF=(E,WORKDWRD)  And do the CLOSE
WRITTEN  DS    0H
         STORAGE RELEASE,LENGTH=XDCBL,ADDR=(R4)  Release DCB buffer

***MUCH LATER***

XDCB     DCB   DDNAME=SYSPRINT,DSORG=PS,MACRF=PM,RECFM=FBA,            *
               LRECL=133,BLKSIZE=3990
XDCBL    EQU   *-XDCB        Length of our DCB so we can copy it

XOPEN    OPEN  (*-*,(OUTPUT)),MODE=31,MF=L
XOPENL   EQU   *-XOPEN

XCLOSE   CLOSE (*-*),MODE=31,MF=L
XCLOSEL  EQU   *-XCLOSE

Reply via email to