| iMatix home page
| << | < | > | >>
SMT Logo SMT
Version 2.81

 

event_send

#include "smtlib.h"
int
event_send (
    const QID *to_queue,                /*  Queue to receive event, or NULL  */
    const QID *from_queue,              /*  Queue to receive reply, or NULL  */
    char   *name,                       /*  Name of event to send            */
    byte   *body,                       /*  Body of message or NULL          */
    size_t  body_size,                  /*  Size of body >= 0                */
    char   *accept_event,               /*  Accept event or NULL             */
    char   *reject_event,               /*  Reject event or NULL             */
    char   *expire_event,               /*  Expire event or NULL             */
    word    timeout                     /*  Timeout in seconds: 0 = none     */
)

Synopsis

Sends an event to an event queue. The event body - if not null or empty - is always copied, crossing memory boundaries. The accept_event, reject_event, and timeout_events are sent back to the sender event queue as required. These events may be specified as null or empty strings. The timeout may be 0 for none, or a value in milliseconds. Returns 0 when successfully completed. The current implementation provides timeouts accurate to a second only. The target queue may be null, in which case the event is ignored, and not sent. This lets you reply to an event without always checking that the reply queue was specified. The event name and reply event names are always stored in uppercase. In case of error, returns -1 and sets smt_errno to one of these values:
SMT NOTREADY smt_init() was not called, or failed
SMT OUTOFMEMORY Not enough heap memory left
SMT NOSUCHQUEUE The target event queue is not known
SMT QUEUEISFULL The target event queue is full

Source Code - (smtlib.c)

{
    static QID
        null_queue = {0, 0};            /*  Indicates a null sender queue    */
    QUEUE   *queue;                     /*  Queue where we will place event  */
    EVENT   *event;                     /*  Allocated event block            */
    size_t  size;                       /*  Total size of event block        */
    char    *string;                    /*  For storing event strings        */

#if (defined (SMT_TRACE))
    trace ("event_send: event=%s", name);
#endif
    ASSERT (name && name [0]);
    if (!smt_alive)                     /*  If SMT API was not correctly     */
      {                                 /*    initialised, forget it         */
        smt_errno = SMT_NOTREADY;
        return (-1);
      }

    /*  If the called did not specify a target queue, ignore                 */
    if (to_queue == NULL || to_queue-> ident == 0)
        return (0);

    if (from_queue == NULL)             /*  If the caller did not specify    */
      {                                 /*    a reply queue, then we can     */
        accept_event =                  /*    ignore the reply events in     */
        reject_event =                  /*    any case.                      */
        expire_event = NULL;
        from_queue   = &null_queue;
      }
    if ((queue = queue lookup (to_queue)) == NULL)
      {
        smt_errno = SMT_NOSUCHQUEUE;
        return (-1);
      }

    /*  Check that we're allowed to create a new event                       */
    if (queue-> max_events > 0
    &&  queue-> max_events == queue-> cur_events)
      {
        smt_errno = SMT_QUEUEISFULL;
        return (-1);
      }

    /*  We allocate the event, body, and return events as a single           */
    /*  block, to reduce access to the heap and make cleaning-up easier.     */
    size = sizeof (EVENT) + body_size + strlen (name) + 1;
    if (accept_event)
        size += strlen (accept_event) + 1;
    if (reject_event)
        size += strlen (reject_event) + 1;
    if (expire_event)
        size += strlen (expire_event) + 1;

    /*  Allocate an EVENT block and attach it to the event list              */
    event = (EVENT *) node_create (queue-> events.prev, size);
    if (event == NULL)
      {
        smt_errno = SMT_OUTOFMEMORY;
        return (-1);
      }

    event-> priority  = SMT_PRIORITY_NULL;
    event-> size      = size;           /*  Event is self-contained          */
    event-> queue     = queue;          /*  Set parent queue address         */
    event-> sender    = *from_queue;    /*    and sender queue               */
    event-> body_size = body_size;      /*  Store body size                  */
    event-> timeout   = timeout? time (NULL) + timeout: 0;

    /*  Store variable-length parts after main event structure               */
    string = (char *) event + sizeof (EVENT);
    event-> name = string;
    strcpy (string, name);
    strupc (string);
    string += strlen (string) + 1;

    if (body_size > 0)
      {
        /*  Store event body                                                 */
        event-> body = (byte *) string;
        memcpy (string, body, body_size);
        string += body_size;
      }
    else
        event-> body = NULL;

    if (accept_event)
      {
        event-> accept_event = string;
        strcpy (string, accept_event);
        strupc (string);
        string += strlen (string) + 1;
      }
    else
        event-> accept_event = NULL;

    if (reject_event)
      {
        event-> reject_event = string;
        strcpy (string, reject_event);
        strupc (string);
        string += strlen (string) + 1;
      }
    else
        event-> reject_event = NULL;

    if (expire_event)
      {
        event-> expire_event = string;
        strcpy (string, expire_event);
        strupc (string);
        string += strlen (string) + 1;
      }
    else
        event-> expire_event = NULL;

    if (timeout)
        queue-> timed_events++;         /*  Count event if timed             */
    queue-> cur_events++;               /*  Count the event                  */
    return (0);                         /*  No errors                        */
}

| << | < | > | >> iMatix Copyright © 1996-99 iMatix Corporation