• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 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 #ifndef MAX_MQ_FD
78 #define MAX_MQ_FD CONFIG_NQUEUE_DESCRIPTORS
79 #endif
80 
81 typedef union send_receive_t {
82     unsigned oth : 3;
83     unsigned grp : 6;
84     unsigned usr : 9;
85     short data;
86 } mode_s;
87 
88 struct mqnotify {
89     pid_t pid;
90     struct sigevent notify;
91 };
92 
93 /* TYPE DEFINITIONS */
94 struct mqarray {
95     UINT32 mq_id : 31;
96     UINT32 unlinkflag : 1;
97     char *mq_name;
98     UINT32 unlink_ref;
99     mode_s mode_data; /* mode data of mqueue */
100     uid_t euid; /* euid of mqueue */
101     gid_t egid; /* egid of mqueue */
102     struct mqnotify mq_notify;
103     LosQueueCB *mqcb;
104     struct mqpersonal *mq_personal;
105 };
106 
107 struct mqpersonal {
108     struct mqarray *mq_posixdes;
109     struct mqpersonal *mq_next;
110     int mq_flags;
111     int mq_mode;  /* Mode of mqueue */
112     UINT32 mq_status;
113     UINT32 mq_refcount;
114 };
115 
116 /**
117  * @ingroup mqueue
118  * Message queue attribute structure
119  */
120 struct mq_attr {
121     long mq_flags;    /**< Message queue flags */
122     long mq_maxmsg;   /**< Maximum number of messages */
123     long mq_msgsize;  /**< Maximum size of a message */
124     long mq_curmsgs;  /**< Number of messages in the current message queue */
125 };
126 
127 /**
128  * @ingroup mqueue
129  * Handle type of a message queue
130  */
131 typedef UINTPTR   mqd_t;
132 
133 /**
134  * @ingroup mqueue
135  *
136  * @par Description:
137  * This API is used to open an existed message queue that has a specified name or create a new message queue.
138  * @attention
139  * <ul>
140  * <li>A message queue does not restrict the read and write permissions.</li>
141  * <li>The length of mqueue name must less than 256.</li>
142  * <li>This operation and closed mqueue scheduling must be used in coordination to release the resource.</li>
143  * <li>The parameter "mode" is not supported.</li>
144  * <li>The "mq_curmsgs" member of the mq_attr structure is not supported.</li>
145  * </ul>
146  *
147  * @param mqName     [IN] Message queue name.
148  * @param openFlag   [IN] Permission attributes of the message queue. The value range is
149  *                        [O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NONBLOCK].
150  * @param mode       [IN] Message queue mode (variadic argument). When oflag is O_CREAT, it requires
151  *                        two additional arguments: mode, which shall be of type mode_t, and attr,
152  *                        which shall be a pointer to an mq_attr structure.
153  * @param attr       [IN] Message queue attribute (variadic argument).
154  *
155  * @retval  mqd_t  The message queue is successfully opened or created.
156  * @retval  (mqd_t)-1 The message queue fails to be opened or created, with any of the following error codes in errno.
157  *
158  *
159  * @par Errors
160  * <ul>
161  * <li><b>ENOENT</b>: O_CREAT flag is not set for oflag, and the message queue specified by name does not exist.</li>
162  * <li><b>EEXIST</b>: Both O_CREAT and O_EXCL are set for oflag, but the message queue
163  *                    specified by name already exists.</li>
164  * <li><b>EINVAL</b>: invalid parameter.</li>
165  * <li><b>ENFILE</b>: The number of opened message queues exceeds the maximum limit.</li>
166  * <li><b>ENOSPC</b>: insufficient memory.</li>
167  * <li><b>ENAMETOOLONG</b>: The message queue name specified by name is too long.</li>
168  * </ul>
169  *
170  * @par Dependency:
171  * <ul><li>mqueue.h</li></ul>
172  * @see mq_close
173  */
174 extern mqd_t mq_open(const char *mqName, int openFlag, ...);
175 
176 /**
177  * @ingroup mqueue
178  *
179  * @par Description:
180  * This API is used to close a message queue that has a specified descriptor.
181  * @attention
182  * <ul>
183  * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_unlink is called.</li>
184  * </ul>
185  *
186  * @param personal   [IN] Message queue descriptor.
187  *
188  * @retval  0    The message queue is successfully closed.
189  * @retval -1    The message queue fails to be closed, with either of the following error codes in errno.
190  *
191  * @par Errors
192  * <ul>
193  * <li><b>EBADF</b>: Invalid message queue descriptor.</li>
194  * <li><b>EAGAIN</b>: Failed to delete the message queue.</li>
195  * <li><b>EFAULT</b>: Failed to free the message queue.</li>
196  * <li><b>EINVAL</b>: Invalid parameter.</li>
197  * </ul>
198  *
199  * @par Dependency:
200  * <ul><li>mqueue.h</li></ul>
201  * @see mq_open
202  */
203 extern int mq_close(mqd_t personal);
204 
205 /**
206  * @ingroup mqueue
207  *
208  * @par Description:
209  * This API is used to remove a message queue that has a specified name.
210  * @attention
211  * <ul>
212  * <li> If the message queue is empty, it will be reclaimed, which is similar to when mq_close is called.</li>
213  * <li> The length of mqueue name must less than 256.</li>
214  * </ul>
215  *
216  * @param mqName   [IN] Message queue name.
217  *
218  * @retval  0    The message queue is successfully removed.
219  * @retval -1    The message queue fails to be removed, with any of the following error codes in errno.
220  *
221  * @par Errors
222  * <ul>
223  * <li><b>ENOENT</b>: The message queue specified by name does not exist.</li>
224  * <li><b>EAGAIN</b>: Failed to delete the message queue.</li>
225  * <li><b>EBUSY</b>: The message queue to be removed is being used.</li>
226  * <li><b>EINVAL</b>: Invalid parameter.</li>
227  * <li><b>ENAMETOOLONG</b>: The name of mqueue is too long.</li>
228  * </ul>
229  *
230  * @par Dependency:
231  * <ul><li>mqueue.h</li></ul>
232  * @see mq_close
233  */
234 extern int mq_unlink(const char *mqName);
235 
236 /**
237  * @ingroup mqueue
238  *
239  * @par Description:
240  * This API is used to put a message with specified message content and length into
241  * a message queue that has a specified descriptor.
242  * @attention
243  * <ul>
244  * <li> Priority-based message processing is not supported.</li>
245  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
246  * </ul>
247  *
248  * @param personal   [IN] Message queue descriptor.
249  * @param msg        [IN] Pointer to the message content to be sent.
250  * @param msgLen     [IN] Length of the message to be sent.
251  * @param msgPrio    [IN] Priority of the message to be sent (the value of this parameter must
252  *                        be 0 because priority-based message sending is not supported. If the
253  *                        value is not 0, this API will cease to work.)
254  *
255  * @retval  0    The message is successfully sent.
256  * @retval -1    The message fails to be sent, with any of the following error codes in errno.
257  *
258  * @par Errors
259  * <ul>
260  * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li>
261  * <li><b>EBADF</b>: The message queue is invalid or not writable.</li>
262  * <li><b>EAGAIN</b>: The message queue is full.</li>
263  * <li><b>EINVAL</b>: Invalid parameter.</li>
264  * <li><b>ENOSPC</b>: Insufficient memory.</li>
265  * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li>
266  * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li>
267  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
268  * </ul>
269  *
270  * @par Dependency:
271  * <ul><li>mqueue.h</li></ul>
272  * @see mq_receive
273  */
274 extern int mq_send(mqd_t personal, const char *msg, size_t msgLen, unsigned int msgPrio);
275 
276 /**
277  * @ingroup mqueue
278  *
279  * @par Description:
280  * This API is used to remove the oldest message from the message queue that has a specified descriptor,
281  * and puts it in the buffer pointed to by msg_ptr.
282  * @attention
283  * <ul>
284  * <li> Priority-based message processing is not supported.</li>
285  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
286  * </ul>
287  *
288  * @param personal   [IN] Message queue descriptor.
289  * @param msg        [IN] Pointer to the message content to be received.
290  * @param msgLen     [IN] Length of the message to be received.
291  * @param msgPrio    [OUT] Priority of the message to be received
292  *                         because priority-based message processing is not supported, this parameter is useless).
293  *
294  * @retval  0    The message is successfully received.
295  * @retval -1    The message fails to be received, with any of the following error codes in the errno.
296  *
297  * @par Errors
298  * <ul>
299  * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li>
300  * <li><b>EBADF</b>: The message queue is invalid or not readable.</li>
301  * <li><b>EAGAIN</b>: The message queue is empty.</li>
302  * <li><b>EINVAL</b>: invalid parameter.</li>
303  * <li><b>EMSGSIZE</b>: The message to be received is too long.</li>
304  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
305  * </ul>
306  *
307  * @par Dependency:
308  * <ul><li>mqueue.h</li></ul>
309  * @see mq_send
310  */
311 extern ssize_t mq_receive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio);
312 
313 /**
314  * @ingroup mqueue
315  *
316  * @par Description:
317  * This API is used to obtain or modify attributes of the message queue that has a specified descriptor.
318  * @attention
319  * <ul>
320  * <li> The mq_maxmsg, mq_msgsize, and mq_curmsgs attributes are not modified
321  *      in the message queue attribute setting.</li>
322  * </ul>
323  *
324  * @param personal    [IN] Message queue descriptor.
325  * @param mqSetAttr   [IN] New attribute of the message queue.
326  * @param MqOldAttr   [OUT] Old attribute of the message queue.
327  *
328  * @retval   0    The message queue attributes are successfully set or get.
329  * @retval   -1   The message queue attributes fail to be set or get,
330  *                with either of the following error codes in the errno.
331  *
332  * @par Errors
333  * <ul>
334  * <li><b>EBADF</b>: Invalid message queue.</li>
335  * <li><b>EINVAL</b>: Invalid parameter.</li>
336  * </ul>
337  *
338  * @par Dependency:
339  * <ul><li>mqueue.h</li></ul>
340  * @see sys_mq_getsetattr
341  */
342 extern int mq_getsetattr(mqd_t personal, const struct mq_attr *mqSetAttr, struct mq_attr *MqOldAttr);
343 
344 /**
345  * @ingroup mqueue
346  *
347  * @par Description:
348  * This API is used to put a message with specified message content and length into
349  * a message queue that has a descriptor at a scheduled time.
350  * @attention
351  * <ul>
352  * <li> Priority-based message processing is not supported.</li>
353  * <li> The expiry time must be later than the current time.</li>
354  * <li> The wait time is a relative time.</li>
355  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
356  * </ul>
357  *
358  * @param mqdes           [IN] Message queue descriptor.
359  * @param msg             [IN] Pointer to the message content to be sent.
360  * @param msgLen          [IN] Length of the message to be sent.
361  * @param msgPrio         [IN] Priority of the message to be sent (the value of this parameter must be 0
362  *                             because priority-based message processing is not supported).
363  * @param absTimeout      [IN] Scheduled time at which the message will be sent. If the value is 0,
364  *                             the message is an instant message.
365  *
366  * @retval   0   The message is successfully sent.
367  * @retval  -1   The message fails to be sent, with any of the following error codes in errno.
368  *
369  * @par Errors
370  * <ul>
371  * <li><b>EINTR</b>: An interrupt is in progress while the message is being sent.</li>
372  * <li><b>EBADF</b>: The message queue is invalid or not writable.</li>
373  * <li><b>EAGAIN</b>: The message queue is full.</li>
374  * <li><b>EINVAL</b>: Invalid parameter.</li>
375  * <li><b>EMSGSIZE</b>: The message to be sent is too long.</li>
376  * <li><b>EOPNOTSUPP</b>: The operation is not supported.</li>
377  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
378  * </ul>
379  *
380  * @par Dependency:
381  * <ul><li>mqueue.h</li></ul>
382  * @see mq_receive
383  */
384 extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen,
385                         unsigned int msgPrio, const struct timespec *absTimeout);
386 
387 /**
388  * @ingroup mqueue
389  *
390  * @par Description:
391  * This API is used to obtain a message with specified message content and length from
392  * a message queue message that has a specified descriptor.
393  * @attention
394  * <ul>
395  * <li> Priority-based message processing is not supported.</li>
396  * <li> The expiry time must be later than the current time.</li>
397  * <li> The wait time is a relative time.</li>
398  * <li> The msg_len should be same to the length of string which msg_ptr point to.</li>
399  * </ul>
400  *
401  * @param personal        [IN] Message queue descriptor.
402  * @param msg             [IN] Pointer to the message content to be received.
403  * @param msgLen          [IN] Length of the message to be received.
404  * @param msgPrio         [OUT] Priority of the message to be received (because priority-based message
405  *                              processing is not supported, this parameter is useless ).
406  * @param absTimeout      [IN] Scheduled time at which the messagewill be received. If the value is 0,
407  *                             the message is an instant message.
408  *
409  * @retval  0    The message is successfully received.
410  * @retval -1    The message fails to be received, with any of the following error codes in errno.
411  *
412  * @par Errors
413  * <ul>
414  * <li><b>EINTR</b>: An interrupt is in progress while the message is being received.</li>
415  * <li><b>EBADF</b>: The message queue is invalid or not readable.</li>
416  * <li><b>EAGAIN</b>: The message queue is empty.</li>
417  * <li><b>EINVAL</b>: invalid parameter.</li>
418  * <li><b>EMSGSIZE</b>: The message to be received is too long.</li>
419  * <li><b>ETIMEDOUT</b>: The operation times out.</li>
420  * </ul>
421  *
422  * @par Dependency:
423  * <ul><li>mqueue.h</li></ul>
424  * @see mq_send
425  */
426 extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen,
427                                unsigned int *msgPrio, const struct timespec *absTimeout);
428 
429 extern void MqueueRefer(int sysFd);
430 extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev);
431 extern VOID OsMqueueCBDestroy(struct mqarray *queueTable);
432 
433 #ifdef __cplusplus
434 #if __cplusplus
435 }
436 #endif /* __cplusplus */
437 #endif /* __cplusplus */
438 
439 #endif
440