SEND

Send a message

WSupported on Windows
USupported on Unix
VSupported on OpenVMS

 

SEND(message, message_id[, queue_num])

Arguments

message

A variable that contains the message to be sent. (a)

message_id

The name that identifies the message (up to six characters, or 39 characters on OpenVMS). (a)

queue_num

(optional) A number identifying the queue to which the message will be sent. The number is operating system specific. (n)

Discussion

The SEND statement sends a message to the same or a different program. The maximum length of the message is system dependent.

The message controller saves the message until it is retrieved by the RECV statement. Only a RECV statement with the same message ID can receive the message.

The sending routine’s name is defined with the MAIN statement. If MAIN is not used in the main routine, the filename is used as the message ID.

If specified, queue_num is either the local queue number or the special queue number of 254 for the group queue and 255 for the global queue. The local queue numbers are assigned from terminal numbers. (See %TNMBR for an explanation of how terminal numbers are determined.)

The non-interactive runtimes (dbs, dbssvc, and dbspriv) do not support SEND and RECV on Windows.

SEND and RECV are supported in .NET on Linux.

Message facilities

There are two types of message facilities to process Synergy messages:

The local message facility is maintained by the runtime. Once the runtime terminates, all messages in the local message facility are lost. However, using this facility has some limitations. Messages can only be sent and received in the same program chain. (On OpenVMS, programs must be bound. See the /BIND[=SECONDARY] compiler option.) Although the queue numbers themselves are essentially ignored (because all messages are local), on each RECV, the queues are retrieved in first in, first out order, starting with queue numbers lower than 254 and higher than 255, followed by 254 (the group queue) and then 255 (the global queue), unless DFLAG is set to reverse the order. If the local message facility is sufficient for your needs, we recommend using it rather than the Synergy message manager, which can incur additional processing overhead.

Unlike the local message facility, the Synergy message manager (synd daemon on Unix and DBL$MSGMGR on OpenVMS) enables you to send messages between processes. The Synergy message manager is a detached program that retains and maintains your messages. Even after the runtime terminates, the messages still exist, and you can run another program and receive those messages.

To use the Synergy message manager on Unix, you must set system option #7 with the DBLOPT environment variable or %OPTION. If you don’t set option #7, Synergy DBL uses the local message facility instead of the Synergy message manager for SEND and RECV statements.

On OpenVMS, the Synergy message manager is used by default. It writes errors to the log file DBLDIR:dblmsgctl.log. To turn off the Synergy message manager and use the local message facility, set system option #47. The message manager can buffer up to 32,000 messages.

On Windows, there is no Synergy message manager; the Synergy runtime (dbr) on Windows uses only the local message facility.

Synergy DBL messages and message queues

Each Synergy DBL message is identified by a combination of the queue number to which it is directed and a message ID of one to six characters (or one to 39 characters on OpenVMS).

There are three kinds of messages:

On Unix, each terminal/login running a Synergy program has its own local message queue into which messages can be inserted. Messages are retrieved from this queue in “first in, first out” order according to message ID. Each message in a terminal’s local queue is called a local message. Unless system option #1 or #13 is set, messages sent via the SEND statement without a queue number are inserted into the local message queue. Messages in the local message queue can only be received by programs running on that terminal. Options #1 and #13 are explained in more detail below.

If you want to send messages that are not directed to this or another terminal, you can use either group messages or global messages. If you are sending to or from a detached process, you need to use a group or global queue and the Synergy message manager.

A global message can be received by any program that explicitly specifies the correct message ID in its RECV statement. The Synergy message manager provides one global message queue for your system. Any message directed to queue number 255 is inserted into the global queue and can be retrieved by referencing the message’s ID.

A group message can be received by any program that specifies the correct message ID and runs under the same group number as the sending program. The Synergy message manager provides one group queue for each group (GID on Unix, and on OpenVMS, the group queue is the same as the global queue). Messages in the group message queue can only be received by programs running under that group ID. Any message directed to queue number 254 is inserted into the group queue.

If you specify system option #13 with DBLOPT or %OPTION, a SEND statement that does not specify a terminal number sends the message to queue number 254 (the group message queue) by default. If you specify system option #1, the message goes to queue number 255 (the global message queue) by default. Option #13 supersedes option #1. Therefore, if you specify both options, option #1 is ignored.

If you need to send a message to a program that will be running in the future, send it to a group or global message queue using the Synergy message manager. Programs whose queue number is negative (for example, detached processes or batch jobs) use the global message queue by default.

Receiving messages

Unless the DFLAG subroutine’s runtime option flag 1 is set, the RECV statement begins searching for a requested message ID in the local queue for that process. If no message ID is specified, RECV assumes the message ID is [SELF]. If RECV can’t find a message that matches the specified ID, it searches next in the group message queue and finally in the global message queue for the first message with the specified ID.

If RECV can’t find the message in any of these queues, it transfers control to the “no message” label. When using the Synergy message manager, you can also use the DFLAG subroutine to indicate that your program should wait for the requested message to become available if no message exists. If you set DFLAG’s runtime option flag 2, your program waits for the message and does not transfer control to the “no message” label.

By default, the RECV statement searches all three message queues in the order described above. However, you can use the RCFLG subroutine to disable the searching of any queue for a particular program. RCFLG enables you to change the search algorithm of the Synergy message manager by setting one or more of its receive option flags.

Special message IDs

On Windows and Unix, both message facilities recognize two message IDs that are specially interpreted:

The square brackets around [SELF] and [INIT] are part of the message IDs.

When [SELF] is specified in the SEND statement, the program determines the message ID to send based on the current program name. When it is specified in the RECV statement, the program determines the message ID to look for based on the current program name. Therefore, if you SEND to [SELF] in program abc, the message ID will be “abc”. If you then chain to program xyz and do a RECV on [SELF], the program will look for “xyz”, not “abc”, and the message will not be found.

Examples

The following example shows a message being sent to another program, which receives it using the [SELF] ID.

The file records.def contains the following:

record cust_master 
name    ,a30 
addr    ,2a40 
city    ,a15 
state   ,a2 
zip     ,d5 
phone   ,d10 
fax     ,d10 

The file custmain.dbl contains the following:

.include "records.def" 
proc 
xcall get_cusrec(cust_master) 
send(cust_master, "cust") 
stop "cust" 
end 

The file customer.dbl contains the following:

main cust 
.include "records.def" 
record 
len ,d5 
proc 
if (%true) then 
recv(cust_master, nomsg, "[SELF]", len) 
else                            ;Recv wasn't chained to 
    begin 
nomsg, 
    xcall get_cusrec(cust_master) 
    end 
end