# Message port functions
[Cooperative scheduler]

The kernel provides a mechanism for sending messages from a thread or interrupt routine to some other thread. More...

## Functions
int | BZ_PortClose (int port)
| Closes a port.
int | BZ_PortOpen (int portid, int signal)
| Opens a port.
int | BZ_PortRead (int portid, BZ_MESG *message)
| Reads a message from a port.
int | BZ_PortSend (int port, int type, int spar, int lpar)
| Sends a message to a port.

## Detailed Description

The kernel provides a mechanism for sending messages from a thread or interrupt routine to some other thread.

The messages themselves are of a fixed structure, containing an 8-bit, a 16-bit and a 32-bit field, intended to be used as message type byte and two parameters that can either deliver a short and an int or, casting a pointer to int, a pointer to the actual message and the length of the message. However, you can use the three fields any way you seem fit, the message subsystem simply delivers them and does not try to interpret their content in any way.

The message delivery is through message ports. These are small objects that are created when you call BZ_Init(). Before using it, a port must be opened by calling BZ_PortOpen(). The calling process will then own that port and whenever a message is available on the port, the process will get an event (see Event (signal) functions). The process then can call BZ_PortRead() which will deliver the next available message from the port. Only one process can own a port at any given time. Like threads, ports are identified by small integers instead of pointers.

The message system is asynchronous, that is, when you send a message you are not suspended until the message is actually read. That of course requires that the kernel buffers the messages, which it does, in the buffer area you provided when you called BZ_Init(). The finite amount of buffer space also means that you can run out of buffers and messages can get lost. You have to make sure that your message consumers do actually consume the messages. Sending a message is fairly fast, it is feasible to use BZ_PortSend() from interrupt routines.

## Function Documentation

int BZ_PortClose | ( | int | port | ) |

Closes a port.

Closes a message port that was opened by BZ_PortOpen(). All messages still queued on the port will be discarded and the port will no longer accept new messages. Only the owner of the port can close it.

Parameters:

  | port | The ID of the port

Return values:

  | BZ_ILLEGAL_PORT | The specified port ID is not valid
  | BZ_NOT_OWNER | The caller does not own the port
  | 0 | Success

Attention:
  This function must not be called from an interrupt. It you do that, the system might crash.

int BZ_PortOpen | ( | int | portid,
|  | int | signal |
| ) |  |  |

Opens a port.

The caller opens the nominated message port for reading. After the successful execution of this function the nominated port will accept messages and will deliver the nominated event to the caller as long as there are unread messages queued on the port. This call does not suspend the caller.

Parameters:

  | portid | The ID of the port to open
  | signal | The bitmap of the event to be delivered to the process. It must not be 0 and must not contain events from the kernel range, that is, an bit with an index larger than BZ_MAX_EVENT. Only one bit should be set, if more than one is specified, then the lowest number bit will be used to signal message availability.

Return values:

  | BZ_ILLEGAL_PORT | The specified port ID is not valid
  | BZ_IN_USE | The specified port is already open
  | BZ_SIGNAL_MASK | The specified signal mask is not valid
  | 0 | Success

Attention:
  This function must not be called from an interrupt. It you do that, the system might crash.

int BZ_PortRead | ( | int | portid,
|  | BZ_MESG * | message |
| ) |  |  |

Reads a message from a port.

The caller must be the owner of the message port. If the port has any messages on it, this function will read the next one. If after reading that message the port will still contain messages, then the nominated event will be delivered to the caller. This call does not suspend the caller.

Parameters:

  | portid | The ID of the port to open
  | message | Pointer to a BZ_MESSAGE structure. The message read from the port will be copied into that structure.

Return values:

  | BZ_ILLEGAL_PORT | The specified port ID is not valid
  | BZ_NOT_OWNER | The caller does not own the port
  | 0 | The port had no messages on it
  | 1 | A message was read into the buffer

Attention:
  This function must not be called from an interrupt. It you do that, the system will crash.

int BZ_PortSend | ( | int | port,
|  | int | type,
|  | int | spar,
|  | int | lpar |
| ) |  |  |

Sends a message to a port.

A message is sent to the port. The port must be open. The caller is not suspended. The owner of the port is notified that a message is available. This function can be called from interrupts.

Parameters:

  | port | The ID of the port
  | type | A message type, a single byte object that will be copied to the 'type' field of the BZ_MESG structure when the owner of the port reads the message.
  | spar | A 2-byte message parameter that will be copied into the 'spar' field of the BZ_MESG structure when the owner of the port reads the message.
  | lpar | A 4-byte message parameter that will be copied into the 'lpar' field of the BZ_MESG structure when the owner of the port reads the message.

Return values:

  | BZ_ILLEGAL_PORT | The specified port ID is not valid
  | BZ_NOT_OPEN | The specified port is not open
  | BZ_OUT_OF_MESG | The kernel has no free message buffers
  | 0 | Success