• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @defgroup mqueue Message queue
34  * @ingroup posix
35  */
36 
37 #ifndef _HWLITEOS_POSIX_MQUEUE_H
38 #define _HWLITEOS_POSIX_MQUEUE_H
39 
40 /* INCLUDES */
41 #include "stdarg.h"
42 #include "stdlib.h"
43 #include "limits.h"
44 #include "los_typedef.h"
45 #include "time.h"
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 
50 #include "los_queue_pri.h"
51 
52 #ifdef __cplusplus
53 #if __cplusplus
54 extern "C" {
55 #endif /* __cplusplus */
56 #endif /* __cplusplus */
57 
58 /**
59  * @ingroup mqueue
60  * Maximum number of messages in a message queue
61  */
62 #define MQ_MAX_MSG_NUM    16
63 
64 /**
65  * @ingroup mqueue
66  * Maximum size of a single message in a message queue
67  */
68 #define MQ_MAX_MSG_LEN    64
69 
70 
71 /* CONSTANTS */
72 
73 #define MQ_USE_MAGIC  0x89abcdef
74 /* not support prio */
75 #define MQ_PRIO_MAX 1
76 
77 typedef union send_receive_t {
78     unsigned oth : 3;
79     unsigned grp : 6;
80     unsigned usr : 9;
81     short data;
82 } mode_s;
83 
84 struct mqnotify {
85     pid_t pid;
86     struct sigevent notify;
87 };
88 
89 /* TYPE DEFINITIONS */
90 struct mqarray {
91     UINT32 mq_id : 31;
92     UINT32 unlinkflag : 1;
93     char *mq_name;
94     UINT32 unlink_ref;
95     mode_s mode_data; /* mode data of mqueue */
96     uid_t euid; /* euid of mqueue */
97     gid_t egid; /* egid of mqueue */
98     struct mqnotify mq_notify;
99     LosQueueCB *mqcb;
100     struct mqpersonal *mq_personal;
101 };
102 
103 struct mqpersonal {
104     struct mqarray *mq_posixdes;
105     struct mqpersonal *mq_next;
106     int mq_flags;
107     int mq_mode;  /* Mode of mqueue */
108     UINT32 mq_status;
109     UINT32 mq_refcount;
110 };
111 
112 /**
113  * @ingroup mqueue
114  * Message queue attribute structure
115  */
116 struct mq_attr {
117     long mq_flags;    /**< Message queue flags */
118     long mq_maxmsg;   /**< Maximum number of messages */
119     long mq_msgsize;  /**< Maximum size of a message */
120     long mq_curmsgs;  /**< Number of messages in the current message queue */
121 };
122 
123 /**
124  * @ingroup mqueue
125  * Handle type of a message queue
126  */
127 typedef UINTPTR   mqd_t;
128 
129 /**
130  * @ingroup mqueue
131  *
132  * @par Description:
133  * This API is used to open an existed message queue that has a specified name or create a new message queue.
134  * @attention
135  * <ul>
136  * <li>A message queue does not restrict the read and write permissions.</li>
137  * <li>The length of mqueue name must less than 256.</li>
138  * <li>This operation and closed mqueue scheduling must be used in coordination to release the resource.</li>
139  * <li>The parameter "mode" is not supported.</li>
140  * <li>The "mq_curmsgs" member of the mq_attr structure is not supported.</li>
141  * </ul>
142  *
143  * @param mqName     [IN] Message queue name.
144  * @param openFlag   [IN] Permission attributes of the message queue. The value range is
145  *                        [O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NONBLOCK].
146  * @param mode       [IN] Message queue mode (variadic argument). When oflag is O_CREAT, it requires
147  *                        two additional arguments: mode, which shall be of type mode_t, and attr,
148  *                        which shall be a pointer to an mq_attr structure.
149  * @param attr       [IN] Message queue attribute (variadic argument).
150  *
151  * @retval  mqd_t  The message queue is successfully opened or created.
152  * @retval  (mqd_t)-1 The message queue fails to be opened or created, with any of the following error codes in errno.
153  *
154  *
155  * @par Errors
156  * <ul>
157  * <li><b>ENOENT</b>: O_CREAT flag is not set for oflag, and the message queue specified by name does not exist.</li>
158  * <li><b>EEXIST</b>: Both O_CREAT and O_EXCL are set for oflag, but the message queue
159  *                    specified by name already exists.</li>
160  * <li><b>EINVAL</b>: invalid parameter.</li>
161  * <li><b>ENFILE</b>: The number of opened message queues exceeds the maximum limit.</li>
162  * <li><b>ENOSPC</b>: insufficient memory.</li>
163  * <li><b>ENAMETOOLONG</b>: The message queue name specified by name is too long.</li>
164  * </ul>
165  *
166  * @par Dependency:
167  * <ul><li>mqueue.h</li></ul>
168  * @see mq_close
169  */
170 extern mqd_t mq_open(const char *mqName, int openFlag, ...);
171 
172 /**
173  * @ingroup mqueue
174  *
175  * @par Description:
176  * This API is used to close a message queue that has a specified descriptor.
177  * @attention
178  * <ul>
179  * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_unlink is called.</li>
180  * </ul>
181  *
182  * @param personal   [IN] Message queue descriptor.
183  *
184  * @retval  0    The message queue is successfully closed.
185  * @retval -1    The message queue fails to be closed, with either of the following error codes in errno.
186  *
187  * @par Errors
188  * <ul>
189  * <li><b>EBADF</b>: Invalid message queue descriptor.</li>
190  * <li><b>EAGAIN</b>: Failed to delete the message queue.</li>
191  * <li><b>EFAULT</b>: Failed to free the message queue.</li>
192  * <li><b>EINVAL</b>: Invalid parameter.</li>
193  * </ul>
194  *
195  * @par Dependency:
196  * <ul><li>mqueue.h</li></ul>
197  * @see mq_open
198  */
199 extern int mq_close(mqd_t personal);
200 
201 /**
202  * @ingroup mqueue
203  *
204  * @par Description:
205  * This API is used to remove a message queue that has a specified name.
206  * @attention
207  * <ul>
208  * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_close is called.</li>
209  * <li> The length of mqueue name must less than 256.</li>
210  * </ul>
211  *
212  * @param mqName   [IN] Message queue name.
213  *
214  * @retval  0    The message queue is successfully removed.
215  * @retval -1    The message queue fails to be removed, with any of the following error codes in errno.
216  *
217  * @par Errors
218  * <ul>
219  * <li><b>ENOENT</b>: The message queue specified by name does not exist.</li>
220  * <li><b>EAGAIN</b>: Failed to delete the message queue.</li>
221  * <li><b>EBUSY</b>: The message queue to be removed is being used.</li>
222  * <li><b>EINVAL</b>: Invalid parameter.</li>
223  * <li><b>ENAMETOOLONG</b>: The name of mqueue is too long.</li>
224  * </ul>
225  *
226  * @par Dependency:
227  * <ul><li>mqueue.h</li></ul>
228  * @see mq_close
229  */
230 extern int mq_unlink(const char *mqName);
231 
232 /**
233  * @ingroup mqueue
234  *
235  * @par Description:
236  * This API is used to put a message with specified message content and length into
237  * a message queue that has a specified descriptor.
238  * @attention
239  * <ul>
240  * <li> Priority-based message processing is not supported.</li>
241  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
242  * </ul>
243  *
244  * @param personal   [IN] Message queue descriptor.
245  * @param msg        [IN] Pointer to the message content to be sent.
246  * @param msgLen     [IN] Length of the message to be sent.
247  * @param msgPrio    [IN] Priority of the message to be sent (the value of this parameter must
248  *                        be 0 because priority-based message sending is not supported. If the
249  *                        value is not 0, this API will cease to work.)
250  *
251  * @retval  0    The message is successfully sent.
252  * @retval -1    The message fails to be sent, with any of the following error codes in errno.
253  *
254  * @par Errors
255  * <ul>
256  * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li>
257  * <li><b>EBADF</b>: The message queue is invalid or not writable.</li>
258  * <li><b>EAGAIN</b>: The message queue is full.</li>
259  * <li><b>EINVAL</b>: Invalid parameter.</li>
260  * <li><b>ENOSPC</b>: Insufficient memory.</li>
261  * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li>
262  * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li>
263  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
264  * </ul>
265  *
266  * @par Dependency:
267  * <ul><li>mqueue.h</li></ul>
268  * @see mq_receive
269  */
270 extern int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio);
271 
272 /**
273  * @ingroup mqueue
274  *
275  * @par Description:
276  * This API is used to remove the oldest message from the message queue that has a specified descriptor,
277  * and puts it in the buffer pointed to by msg_ptr.
278  * @attention
279  * <ul>
280  * <li> Priority-based message processing is not supported.</li>
281  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
282  * </ul>
283  *
284  * @param personal   [IN] Message queue descriptor.
285  * @param msg        [IN] Pointer to the message content to be received.
286  * @param msgLen     [IN] Length of the message to be received.
287  * @param msgPrio    [OUT] Priority of the message to be received
288  *                         because priority-based message processing is not supported, this parameter is useless).
289  *
290  * @retval  0    The message is successfully received.
291  * @retval -1    The message fails to be received, with any of the following error codes in the errno.
292  *
293  * @par Errors
294  * <ul>
295  * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li>
296  * <li><b>EBADF</b>: The message queue is invalid or not readable.</li>
297  * <li><b>EAGAIN</b>: The message queue is empty.</li>
298  * <li><b>EINVAL</b>: invalid parameter.</li>
299  * <li><b>EMSGSIZE</b>: The message to be received is too long.</li>
300  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
301  * </ul>
302  *
303  * @par Dependency:
304  * <ul><li>mqueue.h</li></ul>
305  * @see mq_send
306  */
307 extern ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio);
308 
309 /**
310  * @ingroup mqueue
311  *
312  * @par Description:
313  * This API is used to obtain or modify attributes of the message queue that has a specified descriptor.
314  * @attention
315  * <ul>
316  * <li> The mq_maxmsg, mq_msgsize, and mq_curmsgs attributes are not modified
317  *      in the message queue attribute setting.</li>
318  * </ul>
319  *
320  * @param personal    [IN] Message queue descriptor.
321  * @param mqSetAttr   [IN] New attribute of the message queue.
322  * @param MqOldAttr   [OUT] Old attribute of the message queue.
323  *
324  * @retval   0    The message queue attributes are successfully set or get.
325  * @retval   -1   The message queue attributes fail to be set or get,
326  *                with either of the following error codes in the errno.
327  *
328  * @par Errors
329  * <ul>
330  * <li><b>EBADF</b>: Invalid message queue.</li>
331  * <li><b>EINVAL</b>: Invalid parameter.</li>
332  * </ul>
333  *
334  * @par Dependency:
335  * <ul><li>mqueue.h</li></ul>
336  * @see sys_mq_getsetattr
337  */
338 extern int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr);
339 
340 /**
341  * @ingroup mqueue
342  *
343  * @par Description:
344  * This API is used to put a message with specified message content and length into
345  * a message queue that has a descriptor at a scheduled time.
346  * @attention
347  * <ul>
348  * <li> Priority-based message processing is not supported.</li>
349  * <li> The expiry time must be later than the current time.</li>
350  * <li> The wait time is a relative time.</li>
351  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
352  * </ul>
353  *
354  * @param mqdes           [IN] Message queue descriptor.
355  * @param msg             [IN] Pointer to the message content to be sent.
356  * @param msgLen          [IN] Length of the message to be sent.
357  * @param msgPrio         [IN] Priority of the message to be sent (the value of this parameter must be 0
358  *                             because priority-based message processing is not supported).
359  * @param absTimeout      [IN] Scheduled time at which the message will be sent. If the value is 0,
360  *                             the message is an instant message.
361  *
362  * @retval   0   The message is successfully sent.
363  * @retval  -1   The message fails to be sent, with any of the following error codes in errno.
364  *
365  * @par Errors
366  * <ul>
367  * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li>
368  * <li><b>EBADF</b>: The message queue is invalid or not writable.</li>
369  * <li><b>EAGAIN</b>: The message queue is full.</li>
370  * <li><b>EINVAL</b>: Invalid parameter.</li>
371  * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li>
372  * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li>
373  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
374  * </ul>
375  *
376  * @par Dependency:
377  * <ul><li>mqueue.h</li></ul>
378  * @see mq_receive
379  */
380 extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen,
381                         unsigned int msgPrio, const struct timespec *absTimeout);
382 
383 /**
384  * @ingroup mqueue
385  *
386  * @par Description:
387  * This API is used to obtain a message with specified message content and length from
388  * a message queue message that has a specified descriptor.
389  * @attention
390  * <ul>
391  * <li> Priority-based message processing is not supported.</li>
392  * <li> The expiry time must be later than the current time.</li>
393  * <li> The wait time is a relative time.</li>
394  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
395  * </ul>
396  *
397  * @param personal        [IN] Message queue descriptor.
398  * @param msg             [IN] Pointer to the message content to be received.
399  * @param msgLen          [IN] Length of the message to be received.
400  * @param msgPrio         [OUT] Priority of the message to be received (because priority-based message
401  *                              processing is not supported, this parameter is useless ).
402  * @param absTimeout      [IN] Scheduled time at which the messagewill be received. If the value is 0,
403  *                             the message is an instant message.
404  *
405  * @retval  0    The message is successfully received.
406  * @retval -1    The message fails to be received, with any of the following error codes in errno.
407  *
408  * @par Errors
409  * <ul>
410  * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li>
411  * <li><b>EBADF</b>: The message queue is invalid or not readable.</li>
412  * <li><b>EAGAIN</b>: The message queue is empty.</li>
413  * <li><b>EINVAL</b>: invalid parameter.</li>
414  * <li><b>EMSGSIZE</b>: The message to be received is too long.</li>
415  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
416  * </ul>
417  *
418  * @par Dependency:
419  * <ul><li>mqueue.h</li></ul>
420  * @see mq_send
421  */
422 extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen,
423                                unsigned int *msgPrio, const struct timespec *absTimeout);
424 
425 extern void MqueueRefer(int sysFd);
426 extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev);
427 
428 #ifdef __cplusplus
429 #if __cplusplus
430 }
431 #endif /* __cplusplus */
432 #endif /* __cplusplus */
433 
434 #endif
435