blob: 4c279e1e857276fbdfdcbd55bf7adb79169d09d4 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#ifndef AOS_IPC_LIB_QUEUE_H_
2#define AOS_IPC_LIB_QUEUE_H_
3
4#include "shared_mem.h"
5#include "aos_sync.h"
6
7// TODO(brians) add valgrind client requests to the queue and shared_mem_malloc
8// code to make checking for leaks work better
9// <http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.mempools>
10// describes how
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16// Queues are the primary way to use shared memory. Basic use consists of
17// initializing an aos_type_sig and then calling aos_fetch_queue on it.
18// This aos_queue* can then be used to get a message and write it or to read a
19// message.
20// Queues (as the name suggests) are a FIFO stack of messages. Each combination
21// of name and aos_type_sig will result in a different queue, which means that
22// if you only recompile some code that uses differently sized messages, it will
23// simply use a different queue than the old code.
24//
25// Any pointers returned from these functions can be safely passed to other
26// processes because they are all shared memory pointers.
27// IMPORTANT: Any message pointer must be passed back in some way
28// (aos_queue_free_msg and aos_queue_write_msg are common ones) or the
29// application will leak shared memory.
30// NOTE: Taking a message from read_msg and then passing it to write_msg might
31// work, but it is not guaranteed to.
32
33typedef struct aos_type_sig_t {
34 size_t length; // sizeof(message)
35 int hash; // can differentiate multiple otherwise identical queues
36 int queue_length; // how many messages the queue can hold
37} aos_type_sig;
38
39// Structures that are opaque to users (defined in queue_internal.h).
40typedef struct aos_queue_list_t aos_queue_list;
41typedef struct aos_queue_t aos_queue;
42
43// Retrieves (and creates if necessary) a queue. Each combination of name and
44// signature refers to a completely independent queue.
45aos_queue *aos_fetch_queue(const char *name, const aos_type_sig *sig);
46// Same as above, except sets up the returned queue so that it will put messages
47// on *recycle (retrieved with recycle_sig) when they are freed (after they have
48// been released by all other readers/writers and are not in the queue).
49// The length of recycle_sig determines how many freed messages will be kept.
50// Other code can retrieve recycle_sig and sig separately. However, any frees
51// made using aos_fetch_queue with only sig before the recycle queue has been
52// associated with it will not go on to the recyce queue.
53// Will return NULL for both queues if sig->length != recycle_sig->length or
54// sig->hash == recycle_sig->hash (just to be safe).
55// NOTE: calling this function with the same sig but multiple recycle_sig s
56// will result in each freed message being put onto an undefined recycle_sig.
57aos_queue *aos_fetch_queue_recycle(const char *name, const aos_type_sig *sig,
58 const aos_type_sig *recycle_sig, aos_queue **recycle);
59
60// Constants for passing to opts arguments.
61// #defines so that c code can use queues
62// The non-conflicting ones can be combined with bitwise-or.
63// TODO(brians) prefix these?
64//
65// Causes the returned message to be left in the queue.
66// For reading only.
67#define PEEK 0x0001
68// Reads the last message in the queue instead of just the next one.
69// NOTE: This removes all of the messages until the last one from the queue
70// (which means that nobody else will read them). However, PEEK means to not
71// remove any from the queue, including the ones that are skipped.
72// For reading only.
73#define FROM_END 0x0002
74// Causes reads to return NULL and writes to fail instead of waiting.
75// For reading and writing.
76#define NON_BLOCK 0x0004
77// Causes things to block.
78// IMPORTANT: #defined to 0 so that it is the default. This has to stay.
79// For reading and writing.
80#define BLOCK 0x0000
81// Causes writes to overwrite the oldest message in the queue instead of
82// blocking.
83// For writing only.
84#define OVERRIDE 0x0008
85
86// Frees a message. Does nothing if msg is NULL.
87int aos_queue_free_msg(aos_queue *queue, const void *msg);
88
89// Writes a message into the queue.
90// NOTE: msg must point to at least the length of this queue's worth of valid
91// data to write
92// IMPORTANT: if this returns -1, then the caller must do something with msg
93// (like free it)
94int aos_queue_write_msg(aos_queue *queue, void *msg, int opts);
95// Exactly the same as aos_queue_write_msg, except it automatically frees the
96// message if writing fails.
97static inline int aos_queue_write_msg_free(aos_queue *queue, void *msg, int opts) {
98 const int ret = aos_queue_write_msg(queue, msg, opts);
99 if (ret != 0) {
100 aos_queue_free_msg(queue, msg);
101 }
102 return ret;
103}
104
105// Reads a message out of the queue.
106// The return value will have at least the length of this queue's worth of valid
107// data where it's pointing to.
108// The return value is const because other people might be viewing the same
109// messsage. Do not cast the const away!
110// IMPORTANT: The return value (if not NULL) must eventually be passed to
111// aos_queue_free_msg.
112const void *aos_queue_read_msg(aos_queue *buf, int opts);
113// Exactly the same as aos_queue_read_msg, except it will never return the same
114// message twice with the same index argument. However, it may not return some
115// messages that pass through the queue.
116// *index should start as 0. index does not have to be in shared memory, but it
117// can be
118const void *aos_queue_read_msg_index(aos_queue *queue, int opts, int *index);
119
120// Retrieves ("allocates") a message that can then be written to the queue.
121// NOTE: the return value will be completely uninitialized
122// The return value will have at least the length of this queue's worth of valid
123// data where it's pointing to.
124// Returns NULL for error.
125// IMPORTANT: The return value (if not NULL) must eventually be passed to
126// aos_queue_free_msg.
127void *aos_queue_get_msg(aos_queue *queue);
128
129#ifdef __cplusplus
130}
131#endif
132
133#endif
134