Provides control over program cancels.
call "CBL_CANCEL_PROC" using by value function by reference parameter-block by value cblte-cppb-userdata-length returning status-code
01 cblt-cancel-proc-params typedef. 03 cblte-cppb-version cblt-x4-comp5. *> pic x(4) comp-5 value 0. 03 cblte-cppb-flags cblt-x4-comp5. *> pic x(4) comp-5. 03 cblte-cppb-callback cblt-ppointer *> usage procedure-pointer. 03 cblte-cppb-handle cblt-pointer *> usage pointer. 03 cblte-cppb-userdata cblt-pointer *> usage pointer. 03 cblte-cppb-priority cblt-x4-comp5. *> pic x(4) comp-5.
0 | Installs a cancel-routine at the default priority of 64: |
1 | Installs a cancel-routine at a specified priority. See the section Comments. |
2 | Enables a program to change the priority of a previously installed cancel routine: |
3 | Enables a cancel-registration to be de-installed without causing the cancel-routine to be called. |
4 | Enables a cancel-registration to be de-installed after causing the cancel-routine to be called. Note that the cancel-routine can detect if it is being called because of a de-install rather than a real CANCEL. |
0, 1 | The cancel-routine to install. |
2-4 | Ignored. |
0, 1 | The program-handle of the program to which to attach the cancel-routine, or NULL. See the discussion on program-handles in the section Comments. |
2 | The handle of the cancel-routine to modify registration. |
3, 4 | The handle returned from when function was set to either 0 or 1. This is the handle of the cancel-routine to de-register. |
0, 1 | User-defined data area. See discussion on user-data areas in the section Comments. |
2-4 | Ignored. |
0, 1 | The length of the cblte-cppb-userdata block, or zero. See discussion on user-data areas in the section Comments. |
2-4 | Ignored. |
0, 1 | The handle for the cancel-registration, or NULL. |
2 | Ignored. |
3, 4 | NULL. |
0000 | Success - The operation was performed as requested. |
1000 | Memory allocation error processing request. |
1001 | Bad handle passed to API (Registration-handle). |
1007 | System error (that is, any error not listed here). |
1009 | Bad parameter passed (in function, param, and so on). |
This routine provides a mechanism by which a COBOL program can receive notification of an impending cancel of either itself, or another COBOL program.
Such notification enables a COBOL program to finalize its use of, and deallocate, any resources it has allocated during its existence that are not already handled automatically by the COBOL run-time system or the operating system. These resources are normally those provided by the operating system or run-time system, but could also be some resource provided by another module in the application itself.
The COBOL run-time system performs notifications by processing a list (the cancel-list) which it has associated with the program being canceled. Therefore, to enable a notification, the COBOL run-time system must be instructed to create an entry in the cancel-list. Managing entries in cancel-lists is the purpose of CBL_CANCEL_PROC.
To create an entry in the cancel-list, CBL_CANCEL_PROC needs to know three things:
This information is provided to the run-time system by setting the parameter function to 0 or 1. By doing this, you create an entry in the cancel-list associated with the program cblte-cppb-handle. The entry specifies that the cblte-cppb-callback should be called when notification is due. The position in the list is determined by the value of cancel-priority.
The entry in the cancel-list created can be referenced using the value returned by the registration call in the cblte-cppb-handle parameter on exit. This enables a program to modify the registration at a later time, using this routine with function set to 2, 3 or 4; for example, you can change the priority of the registration, or remove it from the list.
A program-handle is a unique value which the COBOL run-time system associates with a cancelable entity. Therefore, all entry-points in a COBOL program share the same program-handle, as cancelling any entry-point in a COBOL program cancels all entry points in that program.
There are two basic methods of using the CBL_CANCEL_PROC routine, and the amount of work a program needs to do in order to obtain the correct program-handle depends on which method is necessary.
When a program wishes to receive a notification that it is to be canceled, it can make a local registration - usually in its "first time in" code. For this method of registration, the program need only pass NULL as a program-handle. The CBL_CANCEL_PROC routine then automatically locates the correct program-handle and creates an entry in the correct list.
Usually, the cblte-cppb-callback specified in a local registration is an entry-point in the registering program (though it doesn't have to be).
An example would be a program which allocated some resource directly from the operating system and which needed the opportunity to deallocate it before being canceled.
This is a slightly more complicated type of registration, and is used when a service program (that is, a program which manages a resource on behalf of other COBOL programs) needs to receive notification that one of its clients is being canceled. For this method of registration, the program-handle should be obtained using a call to the CBL_GET_PROGRAM_INFO routine. The parameters to CBL_PROGRAM_INFO depend on what functionality you require. The most usual usage would be to get the program-handle of the calling program using function 2 of the CBL_GET_PROGRAM_INFO routine.
Usually, the cblte-cppb-callback specified in a service registration is an entry-point in the service program (though it doesn't have to be).
An example would be a file-handler module which opens and manages files on behalf of several other COBOL programs; when a given program is canceled, all files opened on behalf of that program must be closed automatically according to the semantics of COBOL.
Notice that this example could also be handled by including a local registration in each program which opens a file, which simply closes its files. However, such an approach would be prone to error, does not conform to COBOL semantics, and is very untidy.
When using the CBL_CANCEL_PROC routine for a service program, it is important that when an applicable resource is relinquished by the client program, the notification for it is removed from the cancel-list of that client program. This should be done by setting function to 3 or 4. To make this efficient, the service program could store the program-handle, returned when function is set to 0 or 1, within the resource structure, so that it can be easily located to be passed back as the registration-handle when function is set to 3 or 4.
If the service program fails to de-register a registration using function 3 or 4, a spurious notification will occur when the client program is eventually canceled, leading to unpredictable results.
If the cancel routine cancels other programs, those programs should not themselves have a CBL_CANCEL_PROC installed.
In addition to the three mandatory pieces of information required by CBL_CANCEL_PROC (that is, program-handle, cblte-cppb-callback and cancel-priority; function set to 0 or 1) set using , it can accept an optional fourth, cblte-cppb-userdata.
By using the cblte-cppb-userdata parameter, a program registering a cblte-cppb-callback can specify a parameter to be passed to the cblte-cppb-callback when it is notified that a program has been canceled. You can specify a different cblte-cppb-userdata parameter for each registration, or the same cblte-cppb-userdata field can be specified for multiple registrations. In addition, you can specify that the cblte-cppb-userdata parameter is copied (and the copy passed to the cblte-cppb-callback as a parameter), by specifying a non-zero cblte-cppb-userdata-length parameter.
This facility is extremely useful when used by a service program - the service program does not need to manage a list to associate a client program with a service "handle", but can receive the service "handle" directly as a parameter to the cblte-cppb-callback provided it passed the "handle" to the CBL_CANCEL_PROC registration process as a cblte-cppb-userdata parameter.
This is more convenient than using a cblte-cppb-userdata-length parameter set to zero (applies to Windows environments only), but should typically be used only for small cblte-cppb-userdata areas. If the cblte-cppb-userdata-length parameter is set to non-zero, the specified number of bytes are copied from the address in the cblte-cppb-userdata parameter, and that copy is retained in the list entry. When the program associated with the relevant program-handle is canceled, the cblte-cppb-callback receives the copy of the cblte-cppb-userdata area as a parameter. The copy is deleted automatically by the COBOL run-time system after the cblte-cppb-callback has returned.
It should be noted that the CBL_CANCEL_PROC routine knows nothing about the structure of the cblte-cppb-userdata area passed to it, and only copies a flat memory block. For instance, items of USAGE POINTER embedded within the block will be copied, but the memory to which they point will not. In this case it is probably more appropriate for the application to allocate and copy the entire data structure itself, and pass the copy using a cblte-cppb-userdata-length of zero.
If the cblte-cppb-userdata-length parameter is set to zero (and therefore the original cblte-cppb-userdata parameter specified to the registration process is passed to the cblte-cppb-callback), it is up to the cblte-cppb-callback to delete or deallocate all data structures within that block.
It should be noted that special care must be taken when using this method to pass a cblte-cppb-userdata parameter, especially if the same cblte-cppb-userdata area is registered to more than one registration-handle (the registration handle is returned on exit by the cblte-cppb-handle parameter). Specifically, care must be taken to ensure that any allocated resources are deallocated exactly once, and that allocated resources remain valid until after the last registration-handle to which they are associated has been destroyed. This can usually be accomplished by having a usage-count field somewhere in the cblte-cppb-userdata area, which is incremented each time the cblte-cppb-userdata parameter is registered to a registration-handle and decremented each time a cblte-cppb-callback is called with it as a parameter.
Priorities (set using a value of 1 to function) must be between 0 and 127 for user-code. Priorities 200 to 209 are reserved for File Handler usage. Specifying any other priority value will cause unpredictable results. The default value of 64 should be acceptable for most applications.
This section describes how to implement a cancel routine suitable for installing with CBL_CANCEL_PROC.
working-storage section. 01 cancel-status pic x(4) comp-5. linkage section. 01 cancel-reason pic x(4) comp-5. 01 cancel-flags pic x(4) comp-5. 01 prog-id usage pointer. 01 cblte-cppb-userdata usage pointer. procedure division. entry "user-cblte-cppb-callback" using by value cancel-reason by value cancel-flags by value prog-id by value cblte-cppb-userdata. cblte-cppb-callback section. cblte-cppb-callback-para. *> This is where the code which handles the CANCEL-notification goes. *> The cblte-cppb-userdata field specified in the registration is passed *> to us here, along with the program-id of the program being canceled. *> If this routine is handling registrations which specified a *> cblte-cppb-userdata-field length of zero, then the memory pointed to *> by cblte-cppb-userdata may also need to be freed before returning. exit program returning cancel-status.
The cancel-reason parameter describes the reason for the CANCEL. When set:
Bit 0 (value 1) | CANCEL is due to STOP RUN processing. |
Bit 6 (value 64) | CANCEL is due to DEINSTALL (CBL_CANCEL_PROC called with function set to 4). |
All other bits are reserved and should be ignored.
The cancel-flags parameter is currently reserved and should be ignored.