!382 fix mq by enable mq_notify API

Merge pull request !382 from guweijie/master
This commit is contained in:
openharmony_ci 2021-07-31 03:08:14 +00:00 committed by Gitee
commit a7a25bb0a3
13 changed files with 201 additions and 10 deletions

View File

@ -81,6 +81,11 @@ typedef union send_receive_t {
short data;
} mode_s;
struct mqnotify {
pid_t pid;
struct sigevent notify;
};
/* TYPE DEFINITIONS */
struct mqarray {
UINT32 mq_id : 31;
@ -91,6 +96,7 @@ struct mqarray {
uid_t euid; /* euid of mqueue */
gid_t egid; /* egid of mqueue */
fd_set mq_fdset; /* mqueue sysFd bit map */
struct mqnotify mq_notify;
LosQueueCB *mqcb;
struct mqpersonal *mq_personal;
};
@ -418,6 +424,7 @@ extern ssize_t mq_timedreceive(mqd_t personal, char *msg, size_t msgLen,
unsigned int *msgPrio, const struct timespec *absTimeout);
extern void mqueue_refer(int sysFd);
extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev);
#ifdef __cplusplus
#if __cplusplus

View File

@ -120,6 +120,7 @@ STATIC INT32 DoMqueueDelete(struct mqarray *mqueueCB)
mqueueCB->mode_data.data = 0;
mqueueCB->euid = -1;
mqueueCB->egid = -1;
mqueueCB->mq_notify.pid = 0;
ret = LOS_QueueDelete(mqueueCB->mq_id);
switch (ret) {
@ -204,6 +205,7 @@ STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR
mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK));
mqueueCB->mq_personal->mq_mode = mode;
mqueueCB->mq_personal->mq_refcount = 0;
mqueueCB->mq_notify.pid = 0;
return mqueueCB->mq_personal;
ERROUT:
@ -717,6 +719,35 @@ STATIC INLINE BOOL MqParamCheck(mqd_t personal, const char *msg, size_t msgLen)
return TRUE;
}
/*
* Send realtime a signal to process which registered itself
* successfully by mq_notify.
*/
static void MqSendNotify(struct mqarray *mqueueCB)
{
struct mqnotify *mqnotify = &mqueueCB->mq_notify;
if ((mqnotify->pid) && (mqueueCB->mqcb->readWriteableCnt[OS_QUEUE_READ] == 0)) {
siginfo_t info;
switch (mqnotify->notify.sigev_notify) {
case SIGEV_SIGNAL:
/* sends signal */
/* Create the siginfo structure */
info.si_signo = mqnotify->notify.sigev_signo;
info.si_code = SI_MESGQ;
info.si_value = mqnotify->notify.sigev_value;
OsDispatch(mqnotify->pid, &info, OS_USER_KILL_PERMISSION);
break;
case SIGEV_NONE:
default:
break;
}
/* after notification unregisters process */
mqnotify->pid = 0;
}
}
#define OS_MQ_GOTO_ERROUT_UNLOCK_IF(expr, errcode) \
if (expr) { \
errno = errcode; \
@ -754,6 +785,10 @@ int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, unsigned int ms
mqueueID = mqueueCB->mq_id;
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
if (LOS_ListEmpty(&mqueueCB->mqcb->readWriteList[OS_QUEUE_READ])) {
MqSendNotify(mqueueCB);
}
err = LOS_QueueWriteCopy(mqueueID, (VOID *)msg, (UINT32)msgLen, (UINT32)absTicks);
if (map_errno(err) != ENOERR) {
goto ERROUT;
@ -832,4 +867,82 @@ ssize_t mq_receive(mqd_t personal, char *msg_ptr, size_t msg_len, unsigned int *
return mq_timedreceive(personal, msg_ptr, msg_len, msg_prio, NULL);
}
STATIC INLINE BOOL MqNotifyParamCheck(mqd_t personal, const struct sigevent *sigev)
{
if (personal < 0) {
errno = EBADF;
goto ERROUT;
}
if (sigev != NULL) {
if (sigev->sigev_notify != SIGEV_NONE && sigev->sigev_notify != SIGEV_SIGNAL) {
errno = EINVAL;
goto ERROUT;
}
if (sigev->sigev_notify == SIGEV_SIGNAL && !GOOD_SIGNO(sigev->sigev_signo)) {
errno = EINVAL;
goto ERROUT;
}
}
return TRUE;
ERROUT:
return FALSE;
}
int OsMqNotify(mqd_t personal, const struct sigevent *sigev)
{
struct mqarray *mqueueCB = NULL;
struct mqnotify *mqnotify = NULL;
struct mqpersonal *privateMqPersonal = NULL;
if (!MqNotifyParamCheck(personal, sigev)) {
goto ERROUT;
}
(VOID)pthread_mutex_lock(&g_mqueueMutex);
privateMqPersonal = MqGetPrivDataBuff(personal);
if (privateMqPersonal == NULL) {
goto OUT_UNLOCK;
}
if (privateMqPersonal->mq_status != MQ_USE_MAGIC) {
errno = EBADF;
goto OUT_UNLOCK;
}
mqueueCB = privateMqPersonal->mq_posixdes;
mqnotify = &mqueueCB->mq_notify;
if (sigev == NULL) {
if (mqnotify->pid == LOS_GetCurrProcessID()) {
mqnotify->pid = 0;
}
} else if (mqnotify->pid != 0) {
errno = EBUSY;
goto OUT_UNLOCK;
} else {
switch (sigev->sigev_notify) {
case SIGEV_NONE:
mqnotify->notify.sigev_notify = SIGEV_NONE;
break;
case SIGEV_SIGNAL:
mqnotify->notify.sigev_signo = sigev->sigev_signo;
mqnotify->notify.sigev_value = sigev->sigev_value;
mqnotify->notify.sigev_notify = SIGEV_SIGNAL;
break;
default:
break;
}
mqnotify->pid = LOS_GetCurrProcessID();
}
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
return 0;
OUT_UNLOCK:
(VOID)pthread_mutex_unlock(&g_mqueueMutex);
ERROUT:
return -1;
}
#endif

View File

@ -87,6 +87,18 @@ int SysMqClose(mqd_t personal)
return ret;
}
int SysMqNotify(mqd_t personal, const struct sigevent *sigev)
{
int ret;
MQUEUE_FD_U2K(personal);
ret = OsMqNotify(personal, sigev);
if (ret < 0) {
return -get_errno();
}
return ret;
}
int SysMqGetSetAttr(mqd_t mqd, const struct mq_attr *new, struct mq_attr *old)
{
int ret;

View File

@ -125,6 +125,7 @@ extern int SysMqTimedSend(mqd_t personal, const char *msg, size_t msgLen, unsign
const struct timespec *absTimeout);
extern ssize_t SysMqTimedReceive(mqd_t personal, char *msg, size_t msgLen, unsigned int *msgPrio,
const struct timespec *absTimeout);
extern int SysMqNotify(mqd_t personal, const struct sigevent *sigev);
#endif
extern int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict old, size_t sigsetsize);

View File

@ -216,6 +216,7 @@ SYSCALL_HAND_DEF(__NR_mq_open, SysMqOpen, mqd_t, ARG_NUM_4)
SYSCALL_HAND_DEF(__NR_mq_unlink, SysMqUnlink, int, ARG_NUM_1)
SYSCALL_HAND_DEF(__NR_mq_timedsend, SysMqTimedSend, int, ARG_NUM_5)
SYSCALL_HAND_DEF(__NR_mq_timedreceive, SysMqTimedReceive, ssize_t, ARG_NUM_5)
SYSCALL_HAND_DEF(__NR_mq_notify, SysMqNotify, int, ARG_NUM_2)
SYSCALL_HAND_DEF(__NR_mq_getsetattr, SysMqGetSetAttr, int, ARG_NUM_3)
#ifdef LOSCFG_NET_LWIP_SACK

View File

@ -52,11 +52,6 @@ sources_smoke = [
"smoke/It_posix_queue_028.cpp",
"smoke/It_posix_queue_053.cpp",
"smoke/It_posix_queue_062.cpp",
"smoke/It_posix_queue_205.cpp",
"smoke/It_posix_queue_206.cpp",
"smoke/It_posix_queue_207.cpp",
"smoke/It_posix_queue_208.cpp",
"smoke/It_posix_queue_209.cpp",
]
sources_full = [
@ -200,6 +195,11 @@ sources_full = [
"full/It_posix_queue_202.cpp",
"full/It_posix_queue_203.cpp",
"full/It_posix_queue_204.cpp",
"full/It_posix_queue_205.cpp",
"full/It_posix_queue_206.cpp",
"full/It_posix_queue_207.cpp",
"full/It_posix_queue_208.cpp",
"full/It_posix_queue_209.cpp",
]
if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) {

View File

@ -120,11 +120,6 @@ VOID ItPosixQueue001(VOID);
VOID ItPosixQueue003(VOID);
VOID ItPosixQueue028(VOID);
VOID ItPosixQueue062(VOID);
VOID ItPosixQueue205(VOID);
VOID ItPosixQueue206(VOID);
VOID ItPosixQueue207(VOID);
VOID ItPosixQueue208(VOID);
VOID ItPosixQueue209(VOID);
VOID ItPosixQueue053(VOID);
VOID ItPosixQueue144(VOID);
#endif
@ -274,5 +269,10 @@ VOID ItPosixQueue202(VOID);
VOID ItPosixQueue203(VOID);
VOID ItPosixQueue204(VOID);
VOID ItPosixQueue205(VOID);
VOID ItPosixQueue206(VOID);
VOID ItPosixQueue207(VOID);
VOID ItPosixQueue208(VOID);
VOID ItPosixQueue209(VOID);
#endif
#endif

View File

@ -1354,6 +1354,63 @@ HWTEST_F(PosixMqueueTest, ItPosixQueue204, TestSize.Level0)
{
ItPosixQueue204();
}
#endif
/**
* @tc.name: IT_POSIX_QUEUE_205
* @tc.desc: function for mq_notify:Set sigev_notify to SIGEV_NONE
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(PosixMqueueTest, ItPosixQueue205, TestSize.Level0)
{
ItPosixQueue205();
}
/**
* @tc.name: IT_POSIX_QUEUE_206
* @tc.desc: function for mq_notify:The function returns a failure and the error code is verified.
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(PosixMqueueTest, ItPosixQueue206, TestSize.Level0)
{
ItPosixQueue206();
}
/**
* @tc.name: IT_POSIX_QUEUE_207
* @tc.desc: function for mq_notify:Set sigev_notify to SIGEV_NONE
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(PosixMqueueTest, ItPosixQueue207, TestSize.Level0)
{
ItPosixQueue207();
}
/**
* @tc.name: IT_POSIX_QUEUE_208
* @tc.desc: function for mq_notify:The message queue is not empty.
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
*/
HWTEST_F(PosixMqueueTest, ItPosixQueue208, TestSize.Level0)
{
ItPosixQueue208();
}
/**
* @tc.name: IT_POSIX_QUEUE_209
* @tc.desc: function for mq_notify:The message queue has waiters.
* @tc.type: FUNC
* @tc.require: AR000EEMQ9
**/
HWTEST_F(PosixMqueueTest, ItPosixQueue209, TestSize.Level0)
{
ItPosixQueue209();
}
#endif
} // namespace OHOS