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