From 26ee8b836e346e641de4ecd72284f5d377bca6f8 Mon Sep 17 00:00:00 2001 From: lnlan Date: Tue, 10 Aug 2021 06:40:14 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dmqueue=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E3=80=90=E8=83=8C=E6=99=AF=E3=80=91=201.mqueue?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E5=85=B3=E4=BA=8ENFILE=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=A0=81=E5=8E=8B=E5=8A=9B=E6=B5=8B=E8=AF=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E7=AC=A6=E5=90=88=E9=A2=84=E6=9C=9F=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=202.mq=5Funlink=E5=AF=B9=E4=BA=8Efork=E5=87=BA=E7=9A=84mqueue?= =?UTF-8?q?=E4=B8=8D=E8=B5=B7=E6=95=88=203.=E5=B7=B2=E6=89=93=E5=BC=80?= =?UTF-8?q?=E7=9A=84mqueue=EF=BC=8C=E5=9C=A8fork=E5=90=8E=E4=B8=A4?= =?UTF-8?q?=E8=BF=9B=E7=A8=8B=E5=85=B1=E7=94=A8=E4=B8=80=E4=BB=BDmqpersona?= =?UTF-8?q?l=E4=B8=8D=E5=90=88=E7=90=86=20=E3=80=90=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E3=80=91=201.=20=E7=A1=AE=E8=AE=A4=E6=98=AF?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E5=85=B3=E4=BA=8Emqueue=E7=9A=84fd=5Fset?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E4=BD=8D=E7=BD=AE=E4=B8=8D=E5=90=88=E7=90=86?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=EF=BC=8C=20=E5=B0=86fd=5Fset?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E4=BD=8D=E7=BD=AE=E7=94=B1mqarray=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=93=E8=B0=83=E6=9C=AA=E5=85=A8=E5=B1=80=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=90=8E=EF=BC=8C=E9=97=AE=E9=A2=98=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=202.=E4=B8=8D=E5=90=88=E7=90=86=E7=9A=84unlink=5Fref++?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=EF=BC=8C=E5=8E=BB=E9=99=A4=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=93=8D=E4=BD=9C=EF=BC=8C=E4=BD=BF=E7=94=A8mq=5Fpers?= =?UTF-8?q?onal=20=E9=93=BE=E8=A1=A8=E5=88=A4=E6=96=AD=E4=BD=95=E6=97=B6?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=88=A0=E9=99=A4=203.fork=E6=97=B6=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E5=A4=8D=E5=88=B6=E4=B8=80=E4=BB=BDmqpersonal=20?= =?UTF-8?q?=E3=80=90=E5=BD=B1=E5=93=8D=E3=80=91=20=E5=AF=B9=E7=8E=B0?= =?UTF-8?q?=E6=9C=89=E7=9A=84=E4=BA=A7=E5=93=81=E7=BC=96=E8=AF=91=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E6=9C=89=E5=BD=B1=E5=93=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit re #I43P4T Signed-off-by: lanleinan Change-Id: I09f183cc3a88e5a65201dbc1fc4f4806f78971be --- compat/posix/include/mqueue.h | 3 +- compat/posix/src/mqueue.c | 122 +++++++++++++++++----------------- fs/vfs/operation/fs_file.c | 2 +- 3 files changed, 62 insertions(+), 65 deletions(-) diff --git a/compat/posix/include/mqueue.h b/compat/posix/include/mqueue.h index 123d5540..74d366b3 100644 --- a/compat/posix/include/mqueue.h +++ b/compat/posix/include/mqueue.h @@ -95,7 +95,6 @@ struct mqarray { mode_s mode_data; /* mode data of mqueue */ 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; @@ -423,7 +422,7 @@ extern int mq_timedsend(mqd_t personal, const char *msg, size_t msgLen, 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 void MqueueRefer(int sysFd); extern int OsMqNotify(mqd_t personal, const struct sigevent *sigev); #ifdef __cplusplus diff --git a/compat/posix/src/mqueue.c b/compat/posix/src/mqueue.c index cfc9de38..8e67b035 100644 --- a/compat/posix/src/mqueue.c +++ b/compat/posix/src/mqueue.c @@ -49,6 +49,7 @@ #endif /* GLOBALS */ +STATIC fd_set g_queueFdSet; STATIC struct mqarray g_queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT]; STATIC pthread_mutex_t g_mqueueMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; STATIC struct mqpersonal *g_mqPrivBuf[MAX_MQ_FD]; @@ -247,6 +248,44 @@ ERROUT: return (struct mqpersonal *)-1; } +STATIC INT32 DoMqueueClose(struct mqpersonal *privateMqPersonal) +{ + struct mqarray *mqueueCB = NULL; + struct mqpersonal *tmp = NULL; + + mqueueCB = privateMqPersonal->mq_posixdes; + if (mqueueCB == NULL || mqueueCB->mq_personal == NULL) { + errno = EBADF; + return LOS_NOK; + } + + /* find the personal and remove */ + if (mqueueCB->mq_personal == privateMqPersonal) { + mqueueCB->mq_personal = privateMqPersonal->mq_next; + } else { + for (tmp = mqueueCB->mq_personal; tmp->mq_next != NULL; tmp = tmp->mq_next) { + if (tmp->mq_next == privateMqPersonal) { + break; + } + } + if (tmp->mq_next == NULL) { + errno = EBADF; + return LOS_NOK; + } + tmp->mq_next = privateMqPersonal->mq_next; + } + /* flag no use */ + privateMqPersonal->mq_status = 0; + + /* free the personal */ + (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal); + + if ((mqueueCB->unlinkflag == TRUE) && (mqueueCB->mq_personal == NULL)) { + return DoMqueueDelete(mqueueCB); + } + return LOS_OK; +} + /* Translate a sysFd into privateMqPersonal */ STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal) { @@ -272,29 +311,24 @@ STATIC struct mqpersonal *MqGetPrivDataBuff(mqd_t personal) STATIC INT32 MqAllocSysFd(int maxfdp, struct mqpersonal *privateMqPersonal) { INT32 i; - struct mqarray *mqueueCB = privateMqPersonal->mq_posixdes; - fd_set *fdset = &mqueueCB->mq_fdset; + fd_set *fdset = &g_queueFdSet; for (i = 0; i < maxfdp; i++) { /* sysFd: used bit setting, and get the index of swtmrID buffer */ - if (!(fdset && FD_ISSET(i + MQUEUE_FD_OFFSET, fdset))) { + if (fdset && !(FD_ISSET(i + MQUEUE_FD_OFFSET, fdset))) { FD_SET(i + MQUEUE_FD_OFFSET, fdset); if (!g_mqPrivBuf[i]) { - g_mqPrivBuf[i] = mqueueCB->mq_personal; + g_mqPrivBuf[i] = privateMqPersonal; return i + MQUEUE_FD_OFFSET; } } } - /* there are no more mq sysFd to use, free the personal */ - LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal); - privateMqPersonal = NULL; - mqueueCB->mq_personal = NULL; return -1; } -STATIC VOID MqFreeSysFd(struct mqarray *mqueueCB, mqd_t personal) +STATIC VOID MqFreeSysFd(mqd_t personal) { INT32 sysFd = (INT32)personal; - fd_set *fdset = &mqueueCB->mq_fdset; + fd_set *fdset = &g_queueFdSet; if (fdset && FD_ISSET(sysFd, fdset)) { FD_CLR(sysFd, fdset); g_mqPrivBuf[sysFd - MQUEUE_FD_OFFSET] = NULL; @@ -302,7 +336,7 @@ STATIC VOID MqFreeSysFd(struct mqarray *mqueueCB, mqd_t personal) } /* Mqueue fd reference count */ -void mqueue_refer(int sysFd) +void MqueueRefer(int sysFd) { struct mqarray *mqueueCB = NULL; struct mqpersonal *privateMqPersonal = NULL; @@ -317,10 +351,11 @@ void mqueue_refer(int sysFd) if (mqueueCB == NULL) { goto OUT_UNLOCK; } + privateMqPersonal->mq_refcount++; - mqueueCB->unlink_ref++; OUT_UNLOCK: (VOID)pthread_mutex_unlock(&g_mqueueMutex); + return; } STATIC INT32 MqTryClose(struct mqpersonal *privateMqPersonal) @@ -339,15 +374,6 @@ STATIC INT32 MqTryClose(struct mqpersonal *privateMqPersonal) return FALSE; } -STATIC INT32 MqTryUnlink(struct mqarray *mqueueCB) -{ - if (mqueueCB->unlink_ref == 0) { - return TRUE; - } - mqueueCB->unlink_ref--; - return FALSE; -} - /* Set the mode data bit,for consumer's mode comparing. */ STATIC INT32 MqueueModeAnalysisSet(struct mqpersonal *privateMqPersonal) { @@ -494,6 +520,9 @@ mqd_t mq_open(const char *mqName, int openFlag, ...) } /* Set mode data bit ,just for the first node */ if (MqueueModeAnalysisSet(privateMqPersonal)) { + if ((INT32)(UINTPTR)privateMqPersonal > 0) { + (VOID)DoMqueueClose(privateMqPersonal); + } goto OUT; } } else { @@ -502,15 +531,18 @@ mqd_t mq_open(const char *mqName, int openFlag, ...) } privateMqPersonal = DoMqueueOpen(mqueueCB, openFlag); } -OUT: + if ((INT32)(UINTPTR)privateMqPersonal > 0) { /* alloc sysFd */ sysFd = MqAllocSysFd(MAX_MQ_FD, privateMqPersonal); if (sysFd == -1) { + /* there are no more mq sysFd to use, close the personal */ + (VOID)DoMqueueClose(privateMqPersonal); errno = ENFILE; } mqFd = (mqd_t)sysFd; } +OUT: (VOID)pthread_mutex_unlock(&g_mqueueMutex); return mqFd; } @@ -518,9 +550,7 @@ OUT: int mq_close(mqd_t personal) { INT32 ret = -1; - struct mqarray *mqueueCB = NULL; struct mqpersonal *privateMqPersonal = NULL; - struct mqpersonal *tmp = NULL; (VOID)pthread_mutex_lock(&g_mqueueMutex); @@ -534,47 +564,18 @@ int mq_close(mqd_t personal) errno = EBADF; goto OUT_UNLOCK; } - /* there have other thread used the fd */ + if (!MqTryClose(privateMqPersonal)) { ret = 0; goto OUT_UNLOCK; } - mqueueCB = privateMqPersonal->mq_posixdes; - if (mqueueCB->mq_personal == NULL) { - errno = EBADF; + + ret = DoMqueueClose(privateMqPersonal); + if (ret < 0) { goto OUT_UNLOCK; } + MqFreeSysFd(personal); - /* find the personal and remove */ - if (mqueueCB->mq_personal == privateMqPersonal) { - mqueueCB->mq_personal = privateMqPersonal->mq_next; - } else { - for (tmp = mqueueCB->mq_personal; tmp->mq_next != NULL; tmp = tmp->mq_next) { - if (tmp->mq_next == privateMqPersonal) { - break; - } - } - if (tmp->mq_next == NULL) { - errno = EBADF; - goto OUT_UNLOCK; - } - tmp->mq_next = privateMqPersonal->mq_next; - } - /* flag no use */ - privateMqPersonal->mq_status = 0; - MqFreeSysFd(mqueueCB, personal); - - /* free the personal */ - ret = LOS_MemFree(OS_SYS_MEM_ADDR, privateMqPersonal); - if (ret != LOS_OK) { - errno = EFAULT; - ret = -1; - goto OUT_UNLOCK; - } - - if ((mqueueCB->unlinkflag == TRUE) && (mqueueCB->mq_personal == NULL)) { - ret = DoMqueueDelete(mqueueCB); - } OUT_UNLOCK: (VOID)pthread_mutex_unlock(&g_mqueueMutex); return ret; @@ -667,10 +668,7 @@ int mq_unlink(const char *mqName) errno = ENOENT; goto ERROUT_UNLOCK; } - if (!MqTryUnlink(mqueueCB)) { - (VOID)pthread_mutex_unlock(&g_mqueueMutex); - return 0; - } + if (mqueueCB->mq_personal != NULL) { mqueueCB->unlinkflag = TRUE; } else if (mqueueCB->unlink_ref == 0) { diff --git a/fs/vfs/operation/fs_file.c b/fs/vfs/operation/fs_file.c index 1e600bbb..f9648c87 100644 --- a/fs/vfs/operation/fs_file.c +++ b/fs/vfs/operation/fs_file.c @@ -317,7 +317,7 @@ static void FdRefer(int sysFd) #endif #if defined(LOSCFG_COMPAT_POSIX) if ((sysFd >= MQUEUE_FD_OFFSET) && (sysFd < (MQUEUE_FD_OFFSET + CONFIG_NQUEUE_DESCRIPTORS))) { - mqueue_refer(sysFd); + MqueueRefer(sysFd); } #endif }