!538 支持pipe管道通信机制以及poll多文件描述符检测接口
Merge pull request !538 from JerryH/pipe
This commit is contained in:
commit
c2d3518c42
|
@ -60,6 +60,24 @@
|
|||
#define RANDOM_DEV_PATH "/dev/random"
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
#include "pipe_impl.h"
|
||||
#ifdef LOSCFG_RANDOM_DEV
|
||||
#define PIPE_DEV_FD (RANDOM_DEV_FD + 1)
|
||||
#else
|
||||
#define PIPE_DEV_FD (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS)
|
||||
#endif
|
||||
|
||||
int PollQueryFd(int fd, struct PollTable *table)
|
||||
{
|
||||
if (fd >= PIPE_DEV_FD) {
|
||||
return PipePoll(fd, table);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define FREE_AND_SET_NULL(ptr) do { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
|
@ -285,6 +303,13 @@ int LOS_Open(const char *path, int oflag, ...)
|
|||
}
|
||||
FREE_AND_SET_NULL(canonicalPath);
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
if ((path != NULL) && !strncmp(path, PIPE_DEV_PATH, strlen(PIPE_DEV_PATH))) {
|
||||
return PipeOpen(path, oflag, PIPE_DEV_FD);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_fs == NULL) {
|
||||
errno = ENODEV;
|
||||
return FS_FAILURE;
|
||||
|
@ -308,6 +333,13 @@ int LOS_Close(int fd)
|
|||
return closesocket(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
if (fd >= PIPE_DEV_FD) {
|
||||
return PipeClose(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_fs == NULL) {
|
||||
errno = ENODEV;
|
||||
return FS_FAILURE;
|
||||
|
@ -346,6 +378,13 @@ ssize_t LOS_Read(int fd, void *buf, size_t nbyte)
|
|||
return recv(fd, buf, nbyte, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
if (fd >= PIPE_DEV_FD) {
|
||||
return PipeRead(fd, buf, nbyte);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_fs == NULL) {
|
||||
errno = ENODEV;
|
||||
return FS_FAILURE;
|
||||
|
@ -370,6 +409,13 @@ ssize_t LOS_Write(int fd, const void *buf, size_t nbyte)
|
|||
return send(fd, buf, nbyte, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
if (fd >= PIPE_DEV_FD) {
|
||||
return PipeWrite(fd, buf, nbyte);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_fs == NULL) {
|
||||
errno = ENODEV;
|
||||
return FS_FAILURE;
|
||||
|
|
|
@ -57,6 +57,11 @@ kernel_module(module_name) {
|
|||
if (defined(LOSCFG_POSIX_MQUEUE_API)) {
|
||||
sources += [ "src/mqueue.c" ]
|
||||
}
|
||||
|
||||
if (defined(LOSCFG_POSIX_PIPE_API)) {
|
||||
sources += [ "src/pipe.c" ]
|
||||
sources += [ "src/poll.c" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("public") {
|
||||
|
|
|
@ -59,4 +59,11 @@ config POSIX_MQUEUE_API
|
|||
help
|
||||
Answer Y to enable LiteOS support POSIX Mqueue API.
|
||||
|
||||
|
||||
config POSIX_PIPE_API
|
||||
bool "Enable POSIX Pipe API"
|
||||
default y
|
||||
help
|
||||
Answer Y to enable LiteOS support POSIX Pipe API.
|
||||
|
||||
endif # POSIX_API
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _PIPE_IMPL_H
|
||||
#define _PIPE_IMPL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "los_config.h"
|
||||
#include "poll_impl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define PIPE_DEV_PATH "/dev/pipe"
|
||||
|
||||
UINT32 OsPipeInit(VOID);
|
||||
INT32 PipeOpen(const CHAR *path, INT32 openFlag, INT32 minFd);
|
||||
INT32 PipeClose(INT32 fd);
|
||||
INT32 PipeRead(INT32 fd, VOID *buf, size_t len);
|
||||
INT32 PipeWrite(INT32 fd, const VOID *buf, size_t len);
|
||||
INT32 PipeUnlink(const CHAR *path);
|
||||
INT32 PipePoll(INT32 fd, struct PollTable *table);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _PIPE_IMPL_H */
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _POLL_IMPL_H
|
||||
#define _POLL_IMPL_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_list.h"
|
||||
#include "los_sem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef UINT32 PollEvent;
|
||||
|
||||
struct PollWaitQueue {
|
||||
LOS_DL_LIST queue;
|
||||
};
|
||||
|
||||
struct PollTable;
|
||||
struct PollWaitNode {
|
||||
LOS_DL_LIST node;
|
||||
struct PollTable *table;
|
||||
};
|
||||
|
||||
struct PollTable {
|
||||
struct PollWaitNode *node;
|
||||
PollEvent event;
|
||||
UINT32 sem;
|
||||
BOOL addQueueFlag;
|
||||
};
|
||||
|
||||
VOID PollWaitQueueInit(struct PollWaitQueue *waitQueue);
|
||||
VOID PollNotify(struct PollWaitQueue *waitQueue, PollEvent event);
|
||||
VOID PollWait(struct PollWaitQueue *waitQueue, struct PollTable *table);
|
||||
INT32 PollQueryFd(INT32 fd, struct PollTable *table);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _POLL_IMPL_H */
|
|
@ -0,0 +1,700 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "securec.h"
|
||||
#include "los_fs.h"
|
||||
#include "los_list.h"
|
||||
#include "los_mux.h"
|
||||
#include "los_sem.h"
|
||||
#include "los_debug.h"
|
||||
#include "los_memory.h"
|
||||
#include "pipe_impl.h"
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
|
||||
#define PIPE_DEV_NUM 32
|
||||
#define PIPE_FD_NUM (PIPE_DEV_NUM << 1)
|
||||
#define PIPE_DEV_NAME_MAX 32
|
||||
#define PIPE_DEV_FD_BITMAP_LEN ((PIPE_FD_NUM >> 5) + 1)
|
||||
#define PIPE_DEV_BUF_SIZE 1024
|
||||
#define PIPE_READ 1
|
||||
#define PIPE_WRITE 2
|
||||
|
||||
#define PIPE_DEV_LOCK(mutex) do { \
|
||||
UINT32 __ret = LOS_MuxPend(mutex, LOS_WAIT_FOREVER); \
|
||||
if (__ret != LOS_OK) { \
|
||||
PRINT_ERR("pipe device lock error, ret = %x\n", __ret); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_DEV_UNLOCK(mutex) do { \
|
||||
UINT32 __ret = LOS_MuxPost(mutex); \
|
||||
if (__ret != LOS_OK) { \
|
||||
PRINT_ERR("pipe device unlock error, ret = %x\n", __ret); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_RW_WAIT(sem) do { \
|
||||
LosSemCB *__sem = GET_SEM(sem); \
|
||||
while (__sem->semCount != 0) { \
|
||||
UINT32 __ret = LOS_SemPend(__sem->semID, LOS_WAIT_FOREVER); \
|
||||
if (__ret != LOS_OK) { \
|
||||
PRINT_ERR("pipe device R/W sem wait error, ret = %x\n", __ret); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_RW_POST(sem) do { \
|
||||
LosSemCB *__sem = GET_SEM(sem); \
|
||||
while (__sem->semCount == 0) { \
|
||||
UINT32 __ret = LOS_SemPost(__sem->semID); \
|
||||
if (__ret != LOS_OK) { \
|
||||
PRINT_ERR("pipe device R/W sem post error, ret = %x\n", __ret); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct PipeDev {
|
||||
CHAR devName[PIPE_DEV_NAME_MAX];
|
||||
UINT32 num;
|
||||
UINT32 mutex;
|
||||
LOS_DL_LIST list;
|
||||
UINT32 readSem;
|
||||
UINT32 writeSem;
|
||||
UINT8 *ringBuffer;
|
||||
size_t bufferSize;
|
||||
size_t readIndex;
|
||||
size_t writeIndex;
|
||||
BOOL roll;
|
||||
UINT32 readerCnt;
|
||||
UINT32 writerCnt;
|
||||
UINT32 ref;
|
||||
struct PollWaitQueue wq;
|
||||
};
|
||||
|
||||
struct PipeFdDev {
|
||||
struct PipeDev *dev;
|
||||
BOOL openFlag;
|
||||
};
|
||||
|
||||
STATIC LOS_DL_LIST g_devList = {&g_devList, &g_devList};
|
||||
STATIC UINT32 g_devListMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
|
||||
|
||||
STATIC UINT32 g_devNumBitmap = 0;
|
||||
STATIC UINT32 g_devFdBitmap[PIPE_DEV_FD_BITMAP_LEN] = {0};
|
||||
STATIC struct PipeFdDev g_devFd[PIPE_FD_NUM] = {0};
|
||||
STATIC UINT32 g_devFdMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
|
||||
STATIC INT32 g_devStartFd = 0;
|
||||
|
||||
STATIC INT32 PipeDevNumAlloc(VOID)
|
||||
{
|
||||
UINT32 temp = g_devNumBitmap;
|
||||
INT32 devNum = 0;
|
||||
|
||||
while (temp & 0x1) {
|
||||
devNum++;
|
||||
temp = temp >> 1;
|
||||
}
|
||||
|
||||
if (devNum >= PIPE_DEV_NUM) {
|
||||
return -1;
|
||||
}
|
||||
g_devNumBitmap |= 1U << devNum;
|
||||
|
||||
return devNum;
|
||||
}
|
||||
|
||||
STATIC VOID PipeDevNumFree(INT32 devNum)
|
||||
{
|
||||
if ((devNum < 0) || (devNum >= PIPE_DEV_NUM)) {
|
||||
return;
|
||||
}
|
||||
g_devNumBitmap &= ~(1U << devNum);
|
||||
}
|
||||
|
||||
STATIC struct PipeDev *PipeDevFind(const CHAR *path)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
|
||||
(VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
|
||||
if (!LOS_ListEmpty(&g_devList)) {
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(dev, &g_devList, struct PipeDev, list) {
|
||||
if (!strncmp(dev->devName, path, PIPE_DEV_NAME_MAX)) {
|
||||
(VOID)LOS_MuxPost(g_devListMutex);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
(VOID)LOS_MuxPost(g_devListMutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC size_t PipeRingbufferRead(struct PipeDev *dev, VOID *buf, size_t len)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
if (dev->readIndex < dev->writeIndex) {
|
||||
nbytes = dev->writeIndex - dev->readIndex;
|
||||
} else if (dev->readIndex > dev->writeIndex) {
|
||||
nbytes = dev->bufferSize - dev->readIndex;
|
||||
} else {
|
||||
if (dev->roll == FALSE) {
|
||||
return 0;
|
||||
} else {
|
||||
nbytes = dev->bufferSize - dev->readIndex;
|
||||
}
|
||||
}
|
||||
nbytes = (nbytes > len) ? len : nbytes;
|
||||
(VOID)memcpy_s((char *)buf, len, dev->ringBuffer + dev->readIndex, nbytes);
|
||||
dev->readIndex += nbytes;
|
||||
if (dev->readIndex >= dev->bufferSize) {
|
||||
dev->readIndex = 0;
|
||||
dev->roll = FALSE;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
STATIC size_t PipeRingbufferWrite(struct PipeDev *dev, VOID *buf, size_t len)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
if (dev->readIndex < dev->writeIndex) {
|
||||
nbytes = dev->bufferSize - dev->writeIndex;
|
||||
} else if (dev->readIndex > dev->writeIndex) {
|
||||
nbytes = dev->readIndex - dev->writeIndex;
|
||||
} else {
|
||||
if (dev->roll == TRUE) {
|
||||
return 0;
|
||||
} else {
|
||||
nbytes = dev->bufferSize - dev->writeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
nbytes = (nbytes > len) ? len : nbytes;
|
||||
(VOID)memcpy_s(dev->ringBuffer + dev->writeIndex, dev->bufferSize
|
||||
- dev->writeIndex, buf, nbytes);
|
||||
dev->writeIndex += nbytes;
|
||||
if (dev->writeIndex >= dev->bufferSize) {
|
||||
dev->roll = TRUE;
|
||||
dev->writeIndex = 0;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
STATIC INT32 PipeDevRegister(CHAR *devName, UINT32 len)
|
||||
{
|
||||
INT32 ret;
|
||||
INT32 num = PipeDevNumAlloc();
|
||||
if (num < 0) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct PipeDev *devTemp = NULL;
|
||||
struct PipeDev *dev = LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct PipeDev));
|
||||
if (dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto ERROR;
|
||||
}
|
||||
(VOID)memset_s(dev, sizeof(struct PipeDev), 0, sizeof(struct PipeDev));
|
||||
(VOID)snprintf_s(dev->devName, PIPE_DEV_NAME_MAX, PIPE_DEV_NAME_MAX - 1, "%s%d", PIPE_DEV_PATH, num);
|
||||
(VOID)memcpy_s(devName, len, dev->devName, strlen(dev->devName));
|
||||
|
||||
devTemp = PipeDevFind(dev->devName);
|
||||
if (devTemp != NULL) {
|
||||
ret = -EEXIST;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
ret = LOS_MuxCreate(&dev->mutex);
|
||||
if (ret != LOS_OK) {
|
||||
ret = -ENOSPC;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
ret = LOS_SemCreate(0, &dev->readSem);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_MuxDelete(dev->mutex);
|
||||
ret = -ENOSPC;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
ret = LOS_SemCreate(0, &dev->writeSem);
|
||||
if (ret != LOS_OK) {
|
||||
(VOID)LOS_MuxDelete(dev->mutex);
|
||||
(VOID)LOS_SemDelete(dev->readSem);
|
||||
ret = -ENOSPC;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
dev->num = num;
|
||||
PollWaitQueueInit(&dev->wq);
|
||||
|
||||
(VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
|
||||
LOS_ListAdd(&g_devList, &dev->list);
|
||||
(VOID)LOS_MuxPost(g_devListMutex);
|
||||
|
||||
return ENOERR;
|
||||
ERROR:
|
||||
if (dev != NULL) {
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev);
|
||||
}
|
||||
PipeDevNumFree(num);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC INT32 PipeDevUnregister(struct PipeDev *dev)
|
||||
{
|
||||
BOOL findFlag = FALSE;
|
||||
|
||||
(VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
|
||||
if (LOS_ListEmpty(&g_devList)) {
|
||||
(VOID)LOS_MuxPost(g_devListMutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct PipeDev *tmpDev = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(tmpDev, &g_devList, struct PipeDev, list) {
|
||||
if (tmpDev == dev) {
|
||||
LOS_ListDelete(&dev->list);
|
||||
findFlag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
(VOID)LOS_MuxPost(g_devListMutex);
|
||||
|
||||
if (findFlag != TRUE) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
PipeDevNumFree(dev->num);
|
||||
(VOID)LOS_MuxDelete(dev->mutex);
|
||||
(VOID)LOS_SemDelete(dev->readSem);
|
||||
(VOID)LOS_SemDelete(dev->writeSem);
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev->ringBuffer);
|
||||
dev->ringBuffer = NULL;
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev);
|
||||
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
STATIC INT32 PipeDevFdAlloc(VOID)
|
||||
{
|
||||
UINT32 i = 0;
|
||||
INT32 fd = 0;
|
||||
|
||||
while (g_devFdBitmap[i] & (1U << fd)) {
|
||||
fd++;
|
||||
if (fd == 32) { /* 32: bit index max is 32. */
|
||||
i++;
|
||||
fd = 0;
|
||||
}
|
||||
|
||||
if (i == PIPE_DEV_FD_BITMAP_LEN) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
g_devFdBitmap[i] |= (1U << fd);
|
||||
return (fd + (i << 5)); /* 5: i is the multiple of 32. */
|
||||
}
|
||||
|
||||
STATIC VOID PipeDevFdFree(INT32 fd)
|
||||
{
|
||||
g_devFdBitmap[fd >> 5] &= ~(1U << (fd & 0x1F)); /* 5: fd is the multiple of 32. */
|
||||
}
|
||||
|
||||
STATIC VOID PipePollNotify(struct PipeDev *dev, PollEvent event)
|
||||
{
|
||||
struct PollWaitQueue *waitQueue = &dev->wq;
|
||||
|
||||
if (event & POLLERR) {
|
||||
event &= ~(POLLIN | POLLOUT);
|
||||
}
|
||||
|
||||
PollNotify(waitQueue, event);
|
||||
}
|
||||
|
||||
INT32 PipeOpen(const CHAR *path, INT32 openFlag, INT32 minFd)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
INT32 fd = -1;
|
||||
|
||||
if (path == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((openFlag != O_RDONLY) && (openFlag != O_WRONLY)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = PipeDevFind(path);
|
||||
if (dev == NULL) {
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = PipeDevFdAlloc();
|
||||
if (fd < 0) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
|
||||
g_devFd[fd].dev = dev;
|
||||
g_devFd[fd].openFlag = openFlag;
|
||||
g_devStartFd = minFd;
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
if (openFlag == O_RDONLY) {
|
||||
dev->readerCnt++;
|
||||
} else if (openFlag == O_WRONLY) {
|
||||
dev->writerCnt++;
|
||||
}
|
||||
dev->ref++;
|
||||
|
||||
if (dev->ringBuffer == NULL) {
|
||||
dev->ringBuffer = LOS_MemAlloc(OS_SYS_MEM_ADDR, PIPE_DEV_BUF_SIZE);
|
||||
if (dev->ringBuffer == NULL) {
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
errno = ENOMEM;
|
||||
goto ERROR;
|
||||
}
|
||||
dev->bufferSize = PIPE_DEV_BUF_SIZE;
|
||||
}
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
|
||||
return (fd + minFd);
|
||||
ERROR:
|
||||
if (dev->ringBuffer != NULL) {
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev->ringBuffer);
|
||||
dev->ringBuffer = NULL;
|
||||
}
|
||||
|
||||
PipeDevFdFree(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STATIC INLINE struct PipeFdDev *PipeFdDevGet(INT32 fd)
|
||||
{
|
||||
if (fd < g_devStartFd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd -= g_devStartFd;
|
||||
if (fd >= PIPE_FD_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
return &g_devFd[fd];
|
||||
}
|
||||
|
||||
STATIC struct PipeDev *PipeFd2Dev(INT32 fd)
|
||||
{
|
||||
struct PipeFdDev *devFd = PipeFdDevGet(fd);
|
||||
|
||||
return (devFd != NULL) ? devFd->dev : NULL;
|
||||
}
|
||||
|
||||
INT32 PipeClose(INT32 fd)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
UINT32 openFlag;
|
||||
|
||||
(VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
|
||||
dev = PipeFd2Dev(fd);
|
||||
if (dev == NULL) {
|
||||
errno = ENODEV;
|
||||
goto ERROR;
|
||||
}
|
||||
fd -= g_devStartFd;
|
||||
openFlag = g_devFd[fd].openFlag;
|
||||
g_devFd[fd].dev = NULL;
|
||||
g_devFd[fd].openFlag = FALSE;
|
||||
PipeDevFdFree(fd);
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
if (openFlag == O_RDONLY) {
|
||||
dev->readerCnt--;
|
||||
}
|
||||
|
||||
if (openFlag == O_WRONLY) {
|
||||
dev->writerCnt--;
|
||||
}
|
||||
|
||||
if (dev->readerCnt == 0) {
|
||||
PIPE_RW_POST(dev->writeSem);
|
||||
PipePollNotify(dev, POLLOUT);
|
||||
}
|
||||
|
||||
if (dev->writerCnt == 0) {
|
||||
PIPE_RW_POST(dev->readSem);
|
||||
PipePollNotify(dev, POLLIN);
|
||||
}
|
||||
|
||||
if (--dev->ref == 0) {
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
(VOID)PipeDevUnregister(dev);
|
||||
} else {
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
}
|
||||
|
||||
return ENOERR;
|
||||
ERROR:
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL PipeWriterIsWaiting(UINT32 sem)
|
||||
{
|
||||
LosSemCB *semCB = GET_SEM(sem);
|
||||
UINT32 num = 0;
|
||||
|
||||
while (semCB->semCount == 0) {
|
||||
UINT32 ret = LOS_SemPost(semCB->semID);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("pipe device write sem post error, ret = %x\n", ret);
|
||||
}
|
||||
num++;
|
||||
}
|
||||
return (num <= 1) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
STATIC struct PipeDev *PipeDevGet(INT32 fd)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
|
||||
(VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
|
||||
dev = PipeFd2Dev(fd);
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
INT32 PipeRead(INT32 fd, VOID *buf, size_t len)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
INT32 ret;
|
||||
size_t nread = 0;
|
||||
size_t tmpLen;
|
||||
|
||||
if ((buf == NULL) || (len == 0)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = PipeDevGet(fd);
|
||||
if (dev == NULL) {
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
if ((dev->readIndex == dev->writeIndex) &&
|
||||
(dev->roll == FALSE)) {
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
|
||||
ret = LOS_SemPend(dev->readSem, LOS_WAIT_FOREVER);
|
||||
if (ret != LOS_OK) {
|
||||
errno = EINVAL;
|
||||
goto ERROR;
|
||||
}
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
}
|
||||
|
||||
while (nread < len) {
|
||||
tmpLen = PipeRingbufferRead(dev, (CHAR *)buf + nread, len - nread);
|
||||
if (tmpLen == 0) {
|
||||
PIPE_RW_WAIT(dev->readSem);
|
||||
/* No writer operates at present, which indicates that the write operation may have ended */
|
||||
if (!PipeWriterIsWaiting(dev->writeSem)) {
|
||||
PipePollNotify(dev, POLLOUT);
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
return nread;
|
||||
}
|
||||
PipePollNotify(dev, POLLOUT);
|
||||
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
ret = LOS_SemPend(dev->readSem, LOS_WAIT_FOREVER);
|
||||
if (ret != LOS_OK) {
|
||||
errno = EINVAL;
|
||||
goto ERROR;
|
||||
}
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
}
|
||||
nread += tmpLen;
|
||||
}
|
||||
PIPE_RW_POST(dev->writeSem);
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
PipePollNotify(dev, POLLOUT);
|
||||
|
||||
return nread;
|
||||
ERROR:
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT32 PipeWrite(INT32 fd, const VOID *buf, size_t len)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
INT32 ret;
|
||||
size_t nwrite = 0;
|
||||
size_t tmpLen;
|
||||
|
||||
if ((buf == NULL) || (len == 0)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev = PipeDevGet(fd);
|
||||
if (dev == NULL) {
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
while (nwrite < len) {
|
||||
tmpLen = PipeRingbufferWrite(dev, (char *)buf + nwrite, len - nwrite);
|
||||
if (tmpLen == 0) {
|
||||
PIPE_RW_POST(dev->readSem);
|
||||
PipePollNotify(dev, POLLIN);
|
||||
PIPE_RW_WAIT(dev->writeSem);
|
||||
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
ret = LOS_SemPend(dev->writeSem, LOS_WAIT_FOREVER);
|
||||
if (ret != LOS_OK) {
|
||||
errno = EINVAL;
|
||||
goto ERROR;
|
||||
}
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
}
|
||||
nwrite += tmpLen;
|
||||
}
|
||||
PIPE_RW_POST(dev->readSem);
|
||||
PipePollNotify(dev, POLLIN);
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
|
||||
return nwrite;
|
||||
ERROR:
|
||||
return -1;
|
||||
}
|
||||
|
||||
INT32 PipePoll(INT32 fd, struct PollTable *table)
|
||||
{
|
||||
struct PipeDev *dev = NULL;
|
||||
struct PipeFdDev *devFd = NULL;
|
||||
UINT32 openFlag;
|
||||
INT32 mask;
|
||||
size_t nbytes;
|
||||
PollEvent event = 0;
|
||||
|
||||
if (table == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
|
||||
devFd = PipeFdDevGet(fd);
|
||||
if (devFd == NULL) {
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
}
|
||||
openFlag = devFd->openFlag;
|
||||
dev = devFd->dev;
|
||||
(VOID)LOS_MuxPost(g_devFdMutex);
|
||||
|
||||
PIPE_DEV_LOCK(dev->mutex);
|
||||
if (dev->readIndex == dev->writeIndex) {
|
||||
if (dev->roll == TRUE) {
|
||||
nbytes = dev->bufferSize;
|
||||
} else {
|
||||
nbytes = 0;
|
||||
}
|
||||
} else if (dev->writeIndex > dev->readIndex) {
|
||||
nbytes = dev->writeIndex - dev->readIndex;
|
||||
} else {
|
||||
nbytes = dev->bufferSize - dev->readIndex + dev->writeIndex;
|
||||
}
|
||||
|
||||
if (((openFlag & O_WRONLY) != 0) && (nbytes < (dev->bufferSize - 1))) {
|
||||
event |= POLLOUT;
|
||||
}
|
||||
|
||||
if (((openFlag & O_WRONLY) == 0) && (nbytes > 0)) {
|
||||
event |= POLLIN;
|
||||
}
|
||||
|
||||
mask = event & table->event;
|
||||
if (mask == 0) {
|
||||
PollWait(&dev->wq, table);
|
||||
}
|
||||
PIPE_DEV_UNLOCK(dev->mutex);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
int pipe(int filedes[2])
|
||||
{
|
||||
INT32 ret;
|
||||
CHAR devName[PIPE_DEV_NAME_MAX] = {0};
|
||||
|
||||
ret = PipeDevRegister(devName, PIPE_DEV_NAME_MAX);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
filedes[0] = open(devName, O_RDONLY);
|
||||
filedes[1] = open(devName, O_WRONLY);
|
||||
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
UINT32 OsPipeInit(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
ret = LOS_MuxCreate(&g_devListMutex);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = LOS_MuxCreate(&g_devFdMutex);
|
||||
if (ret != LOS_OK) {
|
||||
LOS_MuxDelete(g_devListMutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "poll.h"
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include "securec.h"
|
||||
#include "poll_impl.h"
|
||||
#include "los_interrupt.h"
|
||||
#include "los_memory.h"
|
||||
|
||||
VOID PollWaitQueueInit(struct PollWaitQueue *waitQueue)
|
||||
{
|
||||
if (waitQueue == NULL) {
|
||||
return;
|
||||
}
|
||||
LOS_ListInit(&waitQueue->queue);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID SetAddPollWaitFlag(struct PollTable *table, BOOL addQueueFlag)
|
||||
{
|
||||
table->addQueueFlag = addQueueFlag;
|
||||
}
|
||||
|
||||
STATIC VOID DestroyPollWait(struct PollTable *table)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct PollWaitNode *waitNode = table->node;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
LOS_ListDelete(&waitNode->node);
|
||||
LOS_IntRestore(intSave);
|
||||
|
||||
(VOID)LOS_MemFree(OS_SYS_MEM_ADDR, waitNode);
|
||||
if (LOS_SemDelete(table->sem) != LOS_OK) {
|
||||
PRINT_ERR("destroy poll sem failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID AddPollWaitQueue(struct PollWaitQueue *waitQueue, struct PollTable *table)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct PollWaitNode *waitNode = LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct PollWaitNode));
|
||||
if (waitNode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
waitNode->table = table;
|
||||
LOS_ListAdd(&waitQueue->queue, &waitNode->node);
|
||||
table->node = waitNode;
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
|
||||
STATIC INT32 WaitSemTime(struct PollTable *table, UINT32 timeout)
|
||||
{
|
||||
if (timeout != 0) {
|
||||
return LOS_SemPend(table->sem, LOS_MS2Tick(timeout));
|
||||
} else {
|
||||
return LOS_SemPend(table->sem, LOS_WAIT_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INT32 QueryFds(struct pollfd *fds, nfds_t nfds, struct PollTable *table)
|
||||
{
|
||||
UINT32 i;
|
||||
INT32 ret;
|
||||
INT32 count = 0;
|
||||
|
||||
if (((nfds != 0) && (fds == NULL)) || (table == NULL)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
struct pollfd *tmpFds = &fds[i];
|
||||
if (tmpFds->fd < 0) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
table->event = tmpFds->events | POLLERR | POLLHUP;
|
||||
|
||||
ret = PollQueryFd(tmpFds->fd, table);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpFds->revents = (tmpFds->events | POLLERR | POLLHUP) & (PollEvent)ret;
|
||||
if (tmpFds->revents != 0) {
|
||||
count++;
|
||||
SetAddPollWaitFlag(table, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
VOID PollNotify(struct PollWaitQueue *waitQueue, PollEvent event)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct PollWaitNode *waitNode = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(waitNode, &waitQueue->queue, struct PollWaitNode, node) {
|
||||
if (!event || (event & waitNode->table->event)) {
|
||||
if (LOS_SemPost(waitNode->table->sem) != LOS_OK) {
|
||||
PRINT_ERR("poll notify sem post failed!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
|
||||
VOID PollWait(struct PollWaitQueue *waitQueue, struct PollTable *table)
|
||||
{
|
||||
if ((waitQueue == NULL) || (table == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (table->addQueueFlag == TRUE) {
|
||||
AddPollWaitQueue(waitQueue, table);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INLINE INT32 PollTimedWait(struct pollfd *fds, nfds_t nfds, struct PollTable *table, INT32 timeout)
|
||||
{
|
||||
struct timespec startTime = {0};
|
||||
struct timespec curTime = {0};
|
||||
INT32 left, last;
|
||||
INT32 ret;
|
||||
INT32 count = 0;
|
||||
|
||||
if (timeout > 0) {
|
||||
clock_gettime(CLOCK_REALTIME, &startTime);
|
||||
}
|
||||
|
||||
left = timeout;
|
||||
while (count == 0) {
|
||||
if (timeout < 0) {
|
||||
ret = WaitSemTime(table, 0);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
} else if (left <= 0) {
|
||||
break;
|
||||
} else if (left > 0) {
|
||||
clock_gettime(CLOCK_REALTIME, &curTime);
|
||||
last = (INT32)((curTime.tv_sec - startTime.tv_sec) * OS_SYS_MS_PER_SECOND +
|
||||
(curTime.tv_nsec - startTime.tv_nsec) / (OS_SYS_NS_PER_SECOND / OS_SYS_MS_PER_SECOND));
|
||||
if (last >= timeout) {
|
||||
break;
|
||||
} else {
|
||||
left = timeout - last;
|
||||
}
|
||||
|
||||
ret = WaitSemTime(table, left);
|
||||
if (ret == LOS_ERRNO_SEM_TIMEOUT) {
|
||||
errno = ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
count = QueryFds(fds, nfds, table);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
struct PollTable table = {0};
|
||||
INT32 count;
|
||||
|
||||
if (LOS_SemCreate(0, &table.sem) != LOS_OK) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetAddPollWaitFlag(&table, ((timeout == 0) ? FALSE : TRUE));
|
||||
|
||||
count = QueryFds(fds, nfds, &table);
|
||||
if (count != 0) {
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
SetAddPollWaitFlag(&table, FALSE);
|
||||
|
||||
count = PollTimedWait(fds, nfds, &table, timeout);
|
||||
|
||||
DONE:
|
||||
DestroyPollWait(&table);
|
||||
return count;
|
||||
}
|
|
@ -649,6 +649,14 @@ extern UINT8 *m_aucSysMem0;
|
|||
#define LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup los_config
|
||||
* Configuration item to enable pipe device.
|
||||
*/
|
||||
#ifndef LOSCFG_PIPE_DEV
|
||||
#define LOSCFG_POSIX_PIPE_API 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
#include "los_lmk.h"
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
#include "pipe_impl.h"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
Function : LOS_Reboot
|
||||
Description : system exception, die in here, wait for watchdog.
|
||||
|
@ -238,6 +242,14 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_KernelInit(VOID)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_POSIX_PIPE_API == 1)
|
||||
ret = OsPipeInit();
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Pipe init failed!\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -721,8 +721,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S
|
|||
|
||||
intSave = LOS_IntLock();
|
||||
if (LOS_ListEmpty(&g_losFreeTask)) {
|
||||
retVal = LOS_ERRNO_TSK_TCB_UNAVAILABLE;
|
||||
OS_GOTO_ERREND();
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_ERRNO_TSK_TCB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask));
|
||||
|
@ -761,10 +761,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S
|
|||
*taskID = taskCB->taskID;
|
||||
OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB);
|
||||
return retVal;
|
||||
|
||||
LOS_ERREND:
|
||||
LOS_IntRestore(intSave);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
Loading…
Reference in New Issue