Table of Contents

Name

linx_receive() - Receive a signal buffer at a LINX endpoint
linx_receive_w_tmo() - Receive a signal buffer with timeout
linx_receive_from() - Receive, but only from a given other endpoint
linx_receive_w_buf() - Receive, but with a preallocated signal buffer

Synopsis

#include <linx_types.h>
#include <linx.h>

int linx_receive(LINX *linx, union LINX_SIGNAL **sig, const LINX_SIGSELECT *sig_sel);

int linx_receive_w_tmo(LINX *linx, union LINX_SIGNAL **sig, const LINX_SIGSELECT *sig_sel, LINX_OSTIME tmo);

int linx_receive_from(LINX *linx, union LINX_SIGNAL **sig, const LINX_SIGSELECT *sig_sel, LINX_OSTIME tmo, LINX_SPID from);

int linx_receive_w_buf(LINX *linx, union LINX_SIGNAL **sig, const LINX_SIGSELECT *sig_sel);

Description

Receive a signal buffer at a LINX endpoint, send from another LINX endpoint. The calls will block until a signal buffer is received or, if applicable, a timeout has elapsed. When a signal buffer with a signal number that matches the sig_sel filter is found in the receive queue, it is returned to the user. This way signals can be "received" in a different order from when they arrived to the LINX endpoint. Signals that have arrived, but have not yet been "received", will stay queued at the LINX endpoint.

linx_receive() will wait indefinitely for a signal buffer that matches the sig_sel filter. sig_sel filters are described in linx(7) .

linx_receive_w_tmo() waits until the provided timeout, tmo, has elapsed or for a signal buffer that matches the sig_sel filter. At timeout, the call is still considered unsuccessful but the LINX_NIL is returned instead of a pointer to a signal buffer.

linx_receive_from() works in the same way as linx_receive_w_tmo() except that it will only accept signal buffers sent from the LINX endpoint, indicated by the spid from.

linx_receive_w_buf() is the only call where a preallocated signal buffer is mandatory. The received signal buffer contents will be stored in sig and if it does not fit, sig will be automatically resized. Apart from this, linx_receive_w_buf() works in the same way as linx_receive(). Note that the provided signal buffer, sig, must be allocated from the same LINX endpoint, on which the signal is received. At an error, LINX will have freed the preallocated buffer and set sig to LINX_NIL. It may be efficent to use a preallocated buffer, if a very large signal buffer is expected, avoiding multiple resizing operations which otherwise might be needed internally in LINX while receiving the buffer.

linx is the handle to the LINX endpoint, via which the signal buffers are received.

sig is the received signal buffer. A preallocated signal buffer may only be used with linx_receive_w_buf(). Do _not_ use a preallocated signal buffer in the other variants of linx_receive(), as this will be lost.

sig_sel is a select filter, defining which type of buffers to receive. It is a list of signal numbers (and a leading value, telling the number of signal numbers in the list). Read more about select filters in linx(7) .

tmo is the maximum number of milliseconds to wait. The value 0 means wait indefinitely, or until receiving a signal buffer.

from is the spid of the other LINX endpoint to receive from. Before linx_receive_from() is used, it is important to attach to the other LINX endpoint with linx_attach(3) and also to include the attach signal number in the sig_sel filter. If this is not done and the other LINX endpoint (with spid from ) is closed, this call will block the entire specified timeout.

If linx is not a valid LINX endpoint, i.e. created with linx_open(3) then abort(3) is called.

Return Value

Returns 0 if successful. If a signal buffer was received, it can be found in sig, otherwise sig will be LINX_NIL. If unsuccessful, -1 is returned and errno is set.

Errors

EINVAL if (in case of linx_receive_w_buf) sig is not a valid signal buffer.

ENOMEM if there is not enough memory.

EBADF, EFAULT, ENOTCONN, ENOTSOCK if the underlying linx structure contains a invalid socket descriptor.

EINTR the call was interrupted by a signal.

Bugs/Limitations

None.

Notes

In case the application needs to wait on multiple sockets of different kinds, the internal socket descriptor in a LINX endpoint can be fetched with linx_get_descriptor(3) and used in a select(2) or poll(2) call to wake up if anything arrives at the LINX endpoint.

Example

In this example the server sends four signals to the client and the client chooses to receive them in the order it wants to.


Signal file (exemple.sig):
#include <linx.h>
#define SIG_X 0x1
#define SIG_Y 0x2
#define SIG_Z 0x3
#define SIG_W 0x4
/* select filter is { number-of-signals, signal, signal, ... } */
static const LINX_SIGSELECT sigsel_any[]      = { 0 };
static const LINX_SIGSELECT sigsel_sig_x_z[]  = { 2, SIG_X, SIG_Z };
static const LINX_SIGSELECT sigsel_sig_w[]    = { 1, SIG_W };
Server:
#include <linx.h>
#include "example.sig"
int
main (int argc, char *argv[])
{
  LINX *linx;
  LINX_SPID client;
  union LINX_SIGNAL *sig;
  /* Open a linx endpoint with huntname "server" */
  linx = linx_open("server", NULL, 0);
  /* Hunt for client */
  linx_hunt(linx, "client", NULL);
  /* Receive hunt signal */
  linx_receive(linx, &sig, LINX_OS_HUNT_SIG);
  /* Retrive client's spid */
  client = linx_sender(linx, &sig);
  /* Free the hunt signal */
  linx_free_buf(linx, &sig);
  /*  Send four signals, they will be stored in the receive
   *  queue on the client in same order as sent but the
   *  client chooses in which order to retrive them from
   *  the queue.
   */
  /* Send signal with signal number SIG_X */
  sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), SIG_X);  
  linx_send(linx, &sig, client);
  /* Send signal with signal number SIG_Y */
  sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), SIG_Y);  
  linx_send(linx, &sig, client);
  /* Send signal with signal number SIG_Z */
  sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), SIG_Z);  
  linx_send(linx, &sig, client);
  /* Send signal with signal number SIG_W */
  sig = linx_alloc(linx, sizeof(LINX_SIGSELECT), SIG_W);  
  linx_send(linx, &sig, client);
  linx_free_buf(linx, &sig);
  /* Close the linx endpoint */
  linx_close (linx);
}
Client:
#include <linx.h>
#include "example.sig"
int
main (int argc, char *argv[])
{
  LINX *linx;
  LINX_SPID client;
  /* Open a linx endpoint with huntname "client" */
  linx = linx_open("client", NULL, 0);
  /* Check for signal SIG_W first */  
  linx_receive(linx, &sig, sigsel_sig_w);
  /* Do work, sig->sig_no is SIG_W */
  /* Free signal when done */
  linx_free_buf(linx, &sig);
  /* Receive the the first signal waiting in the receive queue */
  linx_receive(linx, &sig, sigsel_any);
  /* Do work, sig->sig_no is SIG_X */
  linx_free_buf(linx, &sig);
  /* Receive either SIG_X or SIG_Z from the receive queue. */ 
  linx_receive(linx, &sig, sigsel_sig_x_z);
  /* Do work, sig->sig_no is SIG_Z (SIG_X has been consumed) */
  linx_free_buf(linx, &sig);
  /* Receive the the first signal waiting in the receive queue */
  linx_receive(linx, &sig, sigsel_any);
  /* Do work, sig->sig_no is SIG_Y */
  linx_free_buf(linx, &sig);
  linx_close (linx);
}

See Also

linx(7) , linx_hunt(3) , linx_send(3) , linx_sender(3) , linx_free_buf(3) , linx_alloc(3) , linx_get_descriptor(3) , poll(2) , select(2)

Author

Enea LINX team

Copyright

Copyright (c) 2006-2007, Enea Software AB All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Enea Software AB nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Table of Contents