]> rtime.felk.cvut.cz Git - frescor/frsh-include.git/blob - frsh_distributed.h
df00cabfec2fd43ec89c2b4b5fa62d65164fc1cf
[frescor/frsh-include.git] / frsh_distributed.h
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politécnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
18 //           FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //   This file is part of FRSH (FRescor ScHeduler)
35 //
36 //  FRSH is free software; you can redistribute it and/or modify it
37 //  under terms of the GNU General Public License as published by the
38 //  Free Software Foundation; either version 2, or (at your option) any
39 //  later version.  FRSH is distributed in the hope that it will be
40 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 //  General Public License for more details. You should have received a
43 //  copy of the GNU General Public License along with FRSH; see file
44 //  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 //  Cambridge, MA 02139, USA.
46 //
47 //  As a special exception, including FRSH header files in a file,
48 //  instantiating FRSH generics or templates, or linking other files
49 //  with FRSH objects to produce an executable application, does not
50 //  by itself cause the resulting executable application to be covered
51 //  by the GNU General Public License. This exception does not
52 //  however invalidate any other reasons why the executable file might be
53 //  covered by the GNU Public License.
54 // -----------------------------------------------------------------------
55 //frsh_distributed.h
56 //==============================================
57 //  ******** *******    ********  **      **
58 //  **///// /**////**  **//////  /**     /**
59 //  **      /**   /** /**        /**     /**
60 //  ******* /*******  /********* /**********
61 //  **////  /**///**  ////////** /**//////**
62 //  **      /**  //**        /** /**     /**
63 //  **      /**   //** ********  /**     /**
64 //  //       //     // ////////   //      //
65 //
66 // FRSH(FRescor ScHeduler), pronounced "fresh"
67 //==============================================
68 #ifndef _FRSH_DISTRIBUTED_H_
69 #define _FRSH_DISTRIBUTED_H_
70
71
72 /**
73  * @file frsh_distributed.h
74  **/
75
76
77 #include "frsh_distributed_types.h"
78 #include "frsh_core_types.h"
79
80 FRSH_CPP_BEGIN_DECLS
81
82 /**
83  * @defgroup distributed Distributed module
84  *
85  * This module defines the functions and typedefs for use in
86  * distributed applications.
87  *
88  * Each network is identified by its resource_id and FRSH hides its
89  * characteristics completely.  The type of network is implied with
90  * its ID via a configuration table defined at compile time.
91  *
92  * FRSH uses the "message" as the atomic unit for every exchange.
93  * Queue sizes are measured in number of pending messages.
94  *
95  * FRSH provides a function to calculate the transmision time needed
96  * for a certain message size in a network as well as the maximum
97  * message size that can admit.
98  *
99  * Note also that package delivery guarantee is protocol dependent.
100  * For protocols in which the order is no guaranteed, the application
101  * needs to add extra info to detect possible package disorder.
102  *
103  * Summary of typical steps.
104  *
105  * 1.  Map (internally in FRSH implementation)
106  *     -   node--> network_addresses
107  *     -   network --> resource_id's
108  *     -   unidirectional communication channel --> stream_id
109  *     -   other config --> protocol_info.
110  *
111  * 2.  In a sending node:
112  *     2.1. Negotiates a "network contract" per communication channel
113  *          that is used in the application.  In the contract it is
114  *          specified:
115  *          -  frsh_resource_type = FRSH_RT_NETWORK.
116  *          -  frsh_resource_id = <network id #>
117  *          -  budget:  Time needed to send the required data per period.
118  *                 (you can use frsh_netinfo_*() functions for this).
119  *          -  period:  Period of sendings.
120  *          -  Queueing info:  How will sends be queued at sendEndpoint.
121  *          -  Other protocol dependent function in protocol_contract_info.
122  *     2.2. Create a send_endpoint per any unidirectional stream that will
123  *          be used in sending
124  *          resource_id --> the network through which the stream will
125  *                       flow (this is extra info needed for coherency
126  *                       with the bind).
127  *          destinator --> network_address of the destination.
128  *          stream_id --> the unidirectional communication channel.
129  *     2.3. Bind the send_endpoint to the network contract negotiated
130  *          above.
131  *     2.4. The (processor) sending vres invokes frsh_send_(a)sync() to
132  *          send the data through the corresponding stream.
133  *
134  * 3.  In a receiving node:
135  *     3.1. Create a receive_endpoint per any unidirectional stream
136  *          that will be used in receiving.
137  *     3.2. The processor expecting a reception of message invokes
138  *          frsh_receive_(a)sync() to read the incoming data.
139  *
140  * 4.  When all comunication is finished and the channel is no longer
141  *     needed the nodes will destroy the send and receive endpoints
142  *     and the network contract will be canceled.
143  **/
144
145 /**
146  * frsh_distributed_init(void)
147  *
148  * This operation initializes all the installed networks and the structures
149  * that are necessary for the distributed module. Currently it is called by
150  * frsh_init so it is not necessary that the user calls it again.
151  *
152  *   0: No error \n
153  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
154  *
155  **/
156 int frsh_distributed_init(void);
157
158 //////////////////////////////////////////////////////////////////////
159 //           CONTRACT ASPECTS
160 //////////////////////////////////////////////////////////////////////
161
162 /**
163  * @defgroup distcontract Contract Info for Distributed Systems
164  * @ingroup distributed
165  *
166  * These functions help you calculate the needed budget for network
167  * contracts and also to include protocol dependent info in contract
168  * parameters.
169  *
170  * @{
171  **/
172
173 /**
174  * frsh_network_get_max_message_size()
175  *
176  * This operation gives the maximum number of bytes that can be sent
177  * at a time through the send function when using the network designated by
178  * 'resource_id' and sending it to 'destination'.
179  *
180  * If the application needs to send bigger messages it will have to
181  * split them.
182  *
183  * Some protocols, like IP, are capable of sending large messages
184  * (and use fragmentation internally) but other protocols don't.
185  *
186  * @param[in] resource_id The network we want the tx time from.
187  * @param[in] destination The destination address
188  * @param[out] max_size The maximum number of bytes for each message
189  *
190  * @return
191  *   FRSH_NO_ERROR \n
192  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
193  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
194  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
195  *   a network accessible from the current processing node \n
196  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
197  *   invalid \n
198  *
199  **/
200 int frsh_network_get_max_message_size
201    (const frsh_resource_id_t resource_id,
202     const frsh_network_address_t destination,
203     size_t *max_size);
204
205 /**
206  * frsh_network_bytes_to_budget()
207  *
208  * This operation converts a number of bytes into a temporal budget for
209  * a specific network. Network overheads are not included here but are
210  * considered internally when negotiating a specific contract.
211  *
212  * @param[in] resource_id The network
213  * @param[in] nbytes Number of bytes
214  * @param[out] budget The network budget for nbytes
215  *
216  * @return
217  *   FRSH_NO_ERROR \n
218  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
219  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
220  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
221  *   a network accessible from the current processing node \n
222  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
223  *   than zero \n
224  *
225  **/
226 int frsh_network_bytes_to_budget
227    (const frsh_resource_id_t resource_id,
228     const size_t nbytes,
229     frsh_rel_time_t *budget);
230
231 /**
232  * frsh_network_budget_to_bytes()
233  *
234  * This operation converts a temporal budget into a number of bytes for
235  * a specific network. Network overheads are not included.
236  *
237  * @param[in] resource_id The network
238  * @param[in] budget The network budget for nbytes
239  * @param[out] nbytes Number of bytes
240  *
241  * @return
242  *   FRSH_NO_ERROR \n
243  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
244  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
245  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
246  *   a network accessible from the current processing node \n
247  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
248  *   an invalid time value \n
249  *
250  **/
251 int frsh_network_budget_to_bytes
252    (const frsh_resource_id_t resource_id,
253     const frsh_rel_time_t *budget,
254     size_t *nbytes);
255
256 /**
257  * frsh_network_get_min_effective_budget()
258  *
259  * This operation gets the minimum effective budget for a network. Each message
260  * consumes a contracted budget in "chunks" (i.e: packets) that we call
261  * minimum effective budget.
262  *
263  * A negotiated contract, for N bytes in a period T, means that there is a
264  * virtual resource that reserves for the user:
265  *
266  *   Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
267  *
268  * Note that if the user decides not to send these N bytes at once but, say,
269  * one byte at a time, it will consume one "CHUNK" at a time and the reserved
270  * budget will become exhausted before sending all the bytes.
271  *
272  * @param[in] resource_id The network
273  * @param[out] budget The network budget
274  *
275  * @return
276  *   FRSH_NO_ERROR \n
277  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
278  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
279  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
280  *   a network accessible from the current processing node \n
281  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL \n
282  *
283  **/
284 int frsh_network_get_min_effective_budget
285    (const frsh_resource_id_t resource_id,
286     frsh_rel_time_t *budget);
287
288 /**
289  * frsh_contract_set_queueing_info()
290  *
291  * This function adds queueing parameters that will be used in the
292  * sendEndpoint when the sendEndpoint is bound to the vres.
293  **/
294 int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
295                                     frsh_contract_t *contract);
296
297 /**
298  * frsh_contract_get_queueing_info()
299  *
300  * This function gets the queueing parameters that were specified in
301  * the network contract.
302  **/
303 int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
304                                     frsh_endpoint_queueing_info_t *queueing_info);
305
306 /**
307  * frsh_contract_set_protocol_info
308  *
309  * We add protocol info to the contract
310  **/
311 int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
312                                     frsh_contract_t *contract);
313
314 /**
315  * frsh_contract_get_protocol_info
316  *
317  * We get protocol info from the contract
318  **/
319 int frsh_contract_get_protocol_info(frsh_contract_t *contract,
320                                     frsh_protocol_info_t *protocol_info);
321
322 /**
323  * frsh_contract_marshal
324  *
325  * Convert a contract to a sequence of bytes of minimum size so it can
326  * be sent through the network with the minimum amount of bytes.
327  *
328  **/
329
330 int frsh_contract_marshal(const frsh_contract_t *contract,
331                           unsigned char         *buffer,
332                           const size_t          buffer_size,
333                           size_t                *size);
334
335 /**
336  * frsh_contract_unmarshal
337  *
338  * Convert a sequence of bytes generated by frsh_contract_marshal to a contract
339  *
340  **/
341
342 int frsh_contract_unmarshal(frsh_contract_t      *contract,
343                             const unsigned char  *marshal_bytes,
344                             const size_t         size);
345
346 /*@}*/
347 //////////////////////////////////////////////////////////////////////
348 //           TWO STEP NEGOTIATION
349 //////////////////////////////////////////////////////////////////////
350
351 /**
352  * @defgroup twostepnego Two Step Negotiation
353  * @ingroup distributed
354  *
355  * Using the core services of FRSH, contracts may be negotiated in a
356  * single step. 
357  *
358  * An alternative two-step negotiation process is introduced in the
359  * distribution module: the first step involves the reservation of the
360  * resources, but without the right to use them, and the second step
361  * is the commitment to use those resources.  
362  *
363  * The rationale behind this approach is that in distributed systems,
364  * when a distributed transaction is being negotiated the system
365  * should only commit the virtual resources that were negotiated with
366  * various nodes in the system if the results of all negotiations
367  * match together. This approach enhances the efficiency since the
368  * actual temporal values of the virtual resources on distributed
369  * nodes are only changed if the initiator of the distributed
370  * transaction is satisfied with the results of the negotiations.
371  *
372  * After the reservation, it is not necessary to change the actual
373  * virtual resource attributes (and modifying the schedule) on each
374  * node before the initiator of the distributed transaction knows the
375  * amount of available virtual resources. A renegotiation of a
376  * reserved virtual resource is possible, to harmonize for the
377  * available virtual resources in other parts of the system, before a
378  * final commitment is made.
379  *
380  * @{
381  **/
382
383
384 /**
385  * frsh_contract_negotiate_reservation()
386  *
387  * Negotiate a service contract, obtaining a virtual resource id that
388  * represents a reservation of resources, but without the right to use
389  * those resources until the reservation is committed via
390  * frsh_vres_commit_reservation. In particular, this virtual resource
391  * cannot be bound until committed, but renegotiations are allowed for
392  * it.
393  */
394 int frsh_contract_negotiate_reservation
395   (const frsh_contract_t *contract,
396    frsh_vres_id_t        *vres);
397
398 /**
399  * frsh_vres_commit_reservation()
400  * 
401  * Commit the resources reserved for a virtual resource through a
402  * frsh_contract_negotiate_reservation operation. The effects of
403  * subsequent calls to frsh_contract_negotiate_reservation and
404  * frsh_vres_commit_reservation are equivalent to a single call to
405  * frsh_contract_negotiate.
406  */
407 int frsh_vres_commit_reservation
408    (const frsh_vres_id_t   vres);
409
410 /* @} */
411
412
413
414 //////////////////////////////////////////////////////////////////////
415 //           TRANSMISSION SERVICES
416 //////////////////////////////////////////////////////////////////////
417
418 /**
419  * @defgroup txservices Transmission services
420  * @ingroup distributed
421  *
422  * These functions allow to create and manage endpoints for sending
423  * and receiving and to perform send and receive operations both
424  * synchronously (blocking) and asynchronously (non-blocking).
425  *
426  * @{
427  **/
428
429
430 /**
431  * frsh_send_endpoint_create()
432  *
433  * This operation creates a unidirectional stream input endpoint
434  * through which, after the corresponding binding, it is possible to
435  * send data to a unicast or multicast destination.
436  *
437  * @param[in] resource_id  Identifier of the network referred in the
438  *                        network contract as a resource_id.
439  * @param[in] destination    FRSH abstraction of the protocol address for the
440  *                        destinator node.
441  * @param[in] stream_id   Identifier of the communication channel between
442  *                        the nodes.  Multiplexing is achieved by using
443  *                        different streams between the same nodes and the
444  *                        same network.
445  * @param[in] queueing_info Queueing params of the endpoint (size and
446  *                           policy).
447  * @param[in] protocol_info Optional protocol-dependent info.
448  * @param[out] endpoint   Placeholder for the endpoint object.
449  **/
450 int frsh_send_endpoint_create
451         (frsh_resource_id_t     resource_id,
452          frsh_network_address_t    destination,
453          frsh_stream_id_t       stream_id,
454          frsh_send_endpoint_protocol_info_t protocol_info,
455          frsh_send_endpoint_t  *endpoint);
456
457 /**
458  * frsh_send_endpoint_get_params()
459  *
460  * This operation returns in the variables associated to the
461  * endpoint at creation time.
462  **/
463 int frsh_send_endpoint_get_params
464     (const frsh_send_endpoint_t  endpoint,
465      frsh_resource_id_t        *resource_id,
466      frsh_network_address_t       *destination,
467      frsh_stream_id_t          *stream,
468      frsh_send_endpoint_protocol_info_t  *protocol_info);
469
470 /**
471  * frsh_send_endpoint_destroy()
472  *
473  * This operation eliminates any resources reserved for the referenced
474  * endpoint.  Pending messages will be discarded and processor-vres
475  * waiting in a synchronous operation will be awoken with an error
476  * code.
477  **/
478 int frsh_send_endpoint_destroy
479      (frsh_send_endpoint_t  endpoint);
480
481 /**
482  * frsh_send_endpoint_bind()
483  *
484  * This operation associates a send endpoint with a network vres,
485  * which means that messages sent through this endpoint will consume
486  * the vres's reserved bandwidth and its packets will be sent
487  * according to the contract established for that vres.
488  *
489  * If the endpoint is already bound to another vres, it is effectively
490  * unbound from it and bound to the specified one.  However if a vres
491  * is already bound to another endpoint an error is returned.
492  *
493  * A consistency check is done in which the resource_id specified at
494  * endpoint creation must correspond to the resource_id of the vres
495  * contract.
496  *
497  * @return  0 if successful \n
498  *      FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
499  *                            valid \n
500  *      FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
501  *                               other send endpoint \n
502  *      FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
503  *                               as the one in the endpoint \n
504  **/
505 int frsh_send_endpoint_bind
506   (frsh_vres_id_t      vres,
507    frsh_send_endpoint_t  endpoint);
508
509 /**
510  * frsh_send_endpoint_unbind()
511  *
512  * This operation unbinds a send endpoint from a vres. Endpoints with
513  * no vres associated cannot be used to send data, and they stay in
514  * that state  until they are either eliminated or bound again.
515  *
516  * @return 0 if successful \n
517  *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
518  **/
519 int frsh_send_endpoint_unbind
520   (frsh_send_endpoint_t  endpoint);
521
522 /**
523  * frsh_send_endpoint_get_vres_id()
524  *
525  * This operation copies the id of the vres that is bound to the
526  * specified send endpoint into the variable pointed to by vres.
527  *
528  * @return 0 if successful \n
529  *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
530  *         FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
531  *                               is NULL \n
532  **/
533 int frsh_send_endpoint_get_vres_id
534   (const frsh_send_endpoint_t  endpoint,
535    frsh_vres_id_t            *vres);
536
537 /**
538  * frsh_send_async()
539  *
540  * This operation sends a message stored in msg and of length size
541  * through the given endpoint. The operation is non-blocking and
542  * returns immediately.
543  *
544  * An internal frsh service will schedule the sending of messages and
545  * implement the communications sporadic vres  corresponding to the
546  * network vres bound to the given endpoint.
547  *
548  * @returns 0 if successful \n
549  *       FRSH_ERR_BAD_ARGUMENT if endpoint is not valid \n
550  *       FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres \n
551  *       FRSH_ERR_TOO_LARGE if the message is too large for the
552  *                             network protocol \n
553  *       FRSH_ERR_BUFFER_FULL if the message has been discarded
554  *                            because the queue is full (and does not
555  *                            have the policy FRSH_QP_OLDEST \n
556  **/
557 int frsh_send_async
558   (const frsh_send_endpoint_t  endpoint,
559    const void                  *msg,
560    const size_t                size);
561
562 /**
563  * frsh_send_sync()
564  *
565  * Similar to previous function but now the sending vres gets blocked
566  * until the message is processed.
567  **/
568 int frsh_send_sync
569   (const frsh_send_endpoint_t endpoint,
570    const void                 *msg,
571    size_t                      size);
572
573 /**
574  * frsh_send_endpoint_get_status()
575  *
576  * This function tells the number of messages still pending in the
577  * endpoint queue, whether the network is up or down with some
578  * optional information which is protocol_dependent.
579  **/
580 int frsh_send_endpoint_get_status
581         (const frsh_send_endpoint_t endpoint,
582          int *number_pending_msg,
583          frsh_endpoint_network_status_t *network_status,
584          frsh_protocol_status_t *protocol_status);
585
586 /**
587  * frsh_receive_endpoint_create()
588  *
589  * This operation creates a receive endpoint associated with a
590  * undirectional stream within a network interface of the node.
591  *
592  * Receiving endpoints are not bound to any network vres, this is
593  * because don't originate any traffic.
594  *
595  * Note that the protocol address is not needed for reception because
596  * it can be determined internally by FRSH based on the resource_id.
597  *
598  * Note also that messages may come from diferent originators.
599  *
600  * @param[in] resource_id  Id of the network from which we listen.
601  * @param[in] stream_id  Id of the stream within the network.
602  * @param[in] queueing_info Buffering information(queue size and
603  *                          policy).
604  * @param[in] protocol_info Extra protocol info opaque for the
605  *                          application.
606  * @param[in] endpoin  Placeholder for the endpoint object.
607  *
608  * @return 0 if successful \n
609  *   FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not
610  *      valid \n
611  **/
612 int frsh_receive_endpoint_create
613   (frsh_resource_id_t        resource_id,
614    frsh_stream_id_t          stream_id,
615    frsh_endpoint_queueing_info_t queueing_info,
616    frsh_receive_endpoint_protocol_info_t protocol_info,
617    frsh_receive_endpoint_t  *endpoint);
618
619 /**
620  * frsh_receive_endpoint_get_params()
621  *
622  * This operation returns in the variables associated to the
623  * endpoint at creation time.
624  **/
625 int frsh_receive_endpoint_get_params
626      (const frsh_receive_endpoint_t  endpoint,
627      frsh_resource_id_t        *resource_id,
628      frsh_stream_id_t          *stream,
629      frsh_endpoint_queueing_info_t   *queueing_info,
630      frsh_receive_endpoint_protocol_info_t   *protocol_info);
631
632 /**
633  * frsh_receive_endpoint_destroy()
634  *
635  * This operation eliminates any resources reserved for the referenced
636  * endpoint.  Pending messages will be discarded and processor-vres
637  * waiting in a synchronous operation will be awoken with an error
638  * code.
639  **/
640 int frsh_receive_endpoint_destroy
641      (frsh_receive_endpoint_t  endpoint);
642
643
644 /**
645  * frsh_receive_sync()
646  *
647  * If there are no messages available in the specified receive endpoint
648  * this operation blocks the calling thread waiting for a message to be
649  * received.
650  *
651  * When a message is available, if its size is less than or
652  * equal to the buffer_size, the function stores it in the variable
653  * pointed to by buffer and puts the number of bytes received in the
654  * variable pointed to by message size.
655  *
656  * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
657  * too small for the message received.  In this case the message is
658  * lost.
659  *
660  * Messages arriving at a destination buffer that is full will be
661  * silently discarded (details in the queueing policy of the
662  * endpoint). The application is responsible of reading the receive
663  * endpoints with appropriate regularity, or of using a sequence
664  * number or some other mechanism to detect any lost messages.
665  *
666  * @return 0 if successful \n
667  *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
668  *       buffer or message_size are NULL.\n
669  *     FRSH_ERR_NO_SPACE if the message size is bigger than the
670  *       provided buffer \n
671  **/
672 int frsh_receive_sync
673   (const frsh_receive_endpoint_t  endpoint,
674    void                           *buffer,
675    size_t                         buffer_size,
676    size_t                         *message_size,
677    frsh_network_address_t         *from);
678
679 /**
680  * frsh_receive_async()
681  *
682  * This operation is similar to the previous one but it works in a non
683  * blocking (asynchronous) fashion.  If no message is available it
684  * returns with error FRSH_NO_MESSAGE.
685  *
686  * @return 0 if successful \n
687  *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
688  *       buffer or message_size are NULL \n
689  *     FRSH_NO_MESSAGE if no messages are available in the queue \n
690  *     FRSH_ERR_NO_SPACE if the message size is bigger than the
691  *       provided buffer \n
692  **/
693 int frsh_receive_async
694   (const frsh_receive_endpoint_t  endpoint,
695    void                           *buffer,
696    size_t                         buffer_size,
697    size_t                         *message_size,
698    frsh_network_address_t         *from);
699
700
701 /**
702  * frsh_receive_endpoint_get_status
703  *
704  * This function tells the number of messages still pending in the
705  * endpoint queue, whether the network is up or down and some optional
706  * information which is protocol dependent.
707  **/
708 int frsh_receive_endpoint_get_status
709         (const frsh_receive_endpoint_t endpoint,
710          int *number_pending_messages,
711          frsh_endpoint_network_status_t *network_status,
712          frsh_protocol_status_t *protocol_status);
713
714 /*@}*/
715
716 FRSH_CPP_END_DECLS
717
718 #endif // _FRSH_DISTRIBUTED_H_