Sun Java System Messaging Server 6 2005Q4 MTA Developer's Reference

The process_message() Routine

This caller-supplied routine is invoked by the processing threads to do the actual processing of the messages.

The following code example shows the required syntax for a process_message() routine:


int process_message(void **ctx2, void *ctx1, mta_dq_t *dq_ctx,
                    const char *env_from, int env_from_len);

      

The following table lists the required arguments for a process_message routine, and gives a description of each.

Arguments  

Description  

ctx2

A writable pointer that the process_message() routine can use to store a pointer to a per-thread context. See the description that follows for further details.

ctx1

The caller-supplied private context passed as ctx1 to mtaDequeueStart().

dq_ctx

A dequeue context created by mtaDequeueStart() and representing the message to be processed by this invocation of the process_message() routine.

env_from

A pointer to the envelope From: address for the message to be processed. Since Internet messages are allowed to have zero length envelope From: addresses, this address can have zero length. The address will be NULL terminated.

env_from_len

The length in bytes of the envelope From: string. This length does not include any NULL terminator.

When a processing thread first begins running, it sets the value referenced by ctx2 to NULL. This assignment is made only once per thread and is done before the first call to the process_message() routine. Consequently, on the first call to the process_message routine by a given execution thread, the following test is true:

*ctx2 == NULL

That test will remain true until such time that the process_message() routine itself changes the value by making an assignment to *ctx2. If the process_message() routine needs to maintain state across all calls to itself by the same processing thread, it can allocate memory for a structure to store that state in, and then save a pointer to that memory with ctx2. The following code snippet demonstrates this:


int process_message(void **ctx2, void *ctx1, const char *env_from,
                   size_t env_from_len)
{
    struct our_state_t *state;

    state = (our_state_t *)(*ctx2);
    if (!state)
    {
        /*
         * First call for this thread.
         * Allocate a structure in which to store the state
         * information
         */
        state = (our_state_t *)calloc(1, sizeof(our_state_t));
        if (!state) return(MTA_ABORT);
        *ctx2 = (void *)state;

        /*
         * Set any appropriate initial values for the state
         * structure
         */
       ...
    }
...

      

For a sample process_message() routine, see the example code in the section that follows.