• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "le_task.h"
17 
18 
19 #include "le_loop.h"
20 #include "le_utils.h"
21 
CheckTaskFlags(const BaseTask * task,uint32_t flags)22 int CheckTaskFlags(const BaseTask *task, uint32_t flags)
23 {
24     if (task == NULL) {
25         return 0;
26     }
27     return ((task->flags & flags) == flags);
28 }
29 
GetSocketFd(const TaskHandle task)30 int GetSocketFd(const TaskHandle task)
31 {
32     BaseTask *stream = (BaseTask *)task;
33     return stream->taskId.fd;
34 }
35 
CreateTask(const LoopHandle loopHandle,int fd,const LE_BaseInfo * info,uint32_t size)36 BaseTask *CreateTask(const LoopHandle loopHandle, int fd, const LE_BaseInfo *info, uint32_t size)
37 {
38     if ((size >= LOOP_MAX_BUFFER) || ((size + info->userDataSize) >= LOOP_MAX_BUFFER)) {
39         return NULL;
40     }
41     BaseTask *task = (BaseTask *)malloc(size + info->userDataSize);
42     LE_CHECK(task != NULL, return NULL, "Failed to alloc for task");
43     HASHMAPInitNode(&task->hashNode);
44     // key id
45     task->flags = info->flags;
46     task->taskId.fd = fd;
47     LE_STATUS ret = AddTask((EventLoop *)loopHandle, task);
48     LE_CHECK(ret == LE_SUCCESS, free(task);
49         return NULL, "Failed to alloc for task");
50     task->userDataSize = info->userDataSize;
51     task->userDataOffset = size;
52     task->close = info->close;
53     return task;
54 }
55 
CloseTask(const LoopHandle loopHandle,BaseTask * task)56 void CloseTask(const LoopHandle loopHandle, BaseTask *task)
57 {
58     LE_LOGV("CloseTask");
59     LE_CHECK(loopHandle != NULL && task != NULL, return, "Invalid parameters");
60     if (CheckTaskFlags(task, TASK_STREAM | TASK_CONNECT) ||
61         CheckTaskFlags(task, TASK_EVENT | TASK_ASYNC_EVENT)) {
62         StreamTask *stream = (StreamTask *)task;
63         LE_Buffer *buffer = GetFirstBuffer(stream);
64         while (buffer) {
65             FreeBuffer(loopHandle, stream, (BufferHandle)buffer);
66             buffer = GetFirstBuffer(stream);
67         }
68     }
69     if (task->close != NULL) {
70         task->close((TaskHandle)task);
71     }
72     DelTask((EventLoop *)loopHandle, task);
73 }
74 
CreateBuffer(uint32_t bufferSize)75 LE_Buffer *CreateBuffer(uint32_t bufferSize)
76 {
77     LE_ONLY_CHECK(bufferSize < LOOP_MAX_BUFFER, return NULL);
78     LE_Buffer *buffer = NULL;
79     LE_CHECK((buffer = (LE_Buffer *)malloc(sizeof(LE_Buffer) + bufferSize)) != NULL,
80         return NULL, "Failed to alloc memory for buffer");
81     OH_ListInit(&buffer->node);
82     buffer->buffSize = bufferSize;
83     buffer->dataSize = 0;
84     return buffer;
85 }
86 
IsBufferEmpty(StreamTask * task)87 int IsBufferEmpty(StreamTask *task)
88 {
89     LoopMutexLock(&task->mutex);
90     int ret = ListEmpty(task->buffHead);
91     LoopMutexUnlock(&task->mutex);
92     return ret;
93 }
94 
GetFirstBuffer(StreamTask * task)95 LE_Buffer *GetFirstBuffer(StreamTask *task)
96 {
97     LoopMutexLock(&task->mutex);
98     ListNode *node = task->buffHead.next;
99     LE_Buffer *buffer = NULL;
100     if (node != &task->buffHead) {
101         buffer = ListEntry(node, LE_Buffer, node);
102     }
103     LoopMutexUnlock(&task->mutex);
104     return buffer;
105 }
106 
AddBuffer(StreamTask * task,LE_Buffer * buffer)107 void AddBuffer(StreamTask *task, LE_Buffer *buffer)
108 {
109     LoopMutexLock(&task->mutex);
110     OH_ListAddTail(&task->buffHead, &buffer->node);
111     LoopMutexUnlock(&task->mutex);
112 }
113 
GetNextBuffer(StreamTask * task,const LE_Buffer * next)114 LE_Buffer *GetNextBuffer(StreamTask *task, const LE_Buffer *next)
115 {
116     LoopMutexLock(&task->mutex);
117     LE_Buffer *buffer = NULL;
118     ListNode *node = NULL;
119     if (next == NULL) {
120         node = task->buffHead.next;
121     } else {
122         node = next->node.next;
123     }
124     if (node != &task->buffHead) {
125         buffer = ListEntry(node, LE_Buffer, node);
126     }
127     LoopMutexUnlock(&task->mutex);
128     return buffer;
129 }
130 
FreeBuffer(const LoopHandle loop,StreamTask * task,LE_Buffer * buffer)131 void FreeBuffer(const LoopHandle loop, StreamTask *task, LE_Buffer *buffer)
132 {
133     LE_CHECK(buffer != NULL, return, "Invalid buffer");
134     if (task == NULL) {
135         free(buffer);
136         return;
137     }
138     if (CheckTaskFlags((BaseTask *)task, TASK_STREAM | TASK_CONNECT) ||
139         CheckTaskFlags((BaseTask *)task, TASK_EVENT | TASK_ASYNC_EVENT)) {
140         LoopMutexLock(&task->mutex);
141         OH_ListRemove(&buffer->node);
142         LoopMutexUnlock(&task->mutex);
143     }
144     free(buffer);
145 }
146 
LE_CreateBuffer(const LoopHandle loop,uint32_t bufferSize)147 BufferHandle LE_CreateBuffer(const LoopHandle loop, uint32_t bufferSize)
148 {
149     return (BufferHandle)CreateBuffer(bufferSize);
150 }
151 
LE_FreeBuffer(const LoopHandle loop,const TaskHandle taskHandle,const BufferHandle handle)152 void LE_FreeBuffer(const LoopHandle loop, const TaskHandle taskHandle, const BufferHandle handle)
153 {
154     FreeBuffer(loop, (StreamTask *)taskHandle, (LE_Buffer *)handle);
155 }
156 
LE_GetBufferInfo(const BufferHandle handle,uint32_t * dataSize,uint32_t * buffSize)157 uint8_t *LE_GetBufferInfo(const BufferHandle handle, uint32_t *dataSize, uint32_t *buffSize)
158 {
159     LE_Buffer *buffer = (LE_Buffer *)handle;
160     LE_CHECK(buffer != NULL, return NULL, "Invalid buffer");
161     if (dataSize) {
162         *dataSize = (uint32_t)buffer->dataSize;
163     }
164     if (buffSize) {
165         *buffSize = (uint32_t)buffer->buffSize;
166     }
167     return buffer->data;
168 }
169 
LE_Send(const LoopHandle loopHandle,const TaskHandle taskHandle,const BufferHandle buffHandle,uint32_t buffLen)170 LE_STATUS LE_Send(const LoopHandle loopHandle,
171     const TaskHandle taskHandle, const BufferHandle buffHandle, uint32_t buffLen)
172 {
173     EventLoop *loop = (EventLoop *)loopHandle;
174     if (((BaseTask *)taskHandle)->flags & TASK_FLAGS_INVALID) {
175         LE_FreeBuffer(loopHandle, taskHandle, buffHandle);
176         return LE_INVALID_TASK;
177     }
178     LE_Buffer *buffer = (LE_Buffer *)buffHandle;
179     buffer->dataSize = buffLen;
180     if (CheckTaskFlags((BaseTask *)taskHandle, TASK_STREAM | TASK_CONNECT)) {
181         AddBuffer((StreamTask *)taskHandle, buffer);
182     } else if (CheckTaskFlags((BaseTask *)taskHandle, TASK_EVENT | TASK_ASYNC_EVENT)) {
183         AddBuffer((StreamTask *)taskHandle, buffer);
184     }
185     loop->modEvent(loop, (BaseTask *)taskHandle, Event_Write);
186     return LE_SUCCESS;
187 }
188 
LE_CloseTask(const LoopHandle loopHandle,const TaskHandle taskHandle)189 void LE_CloseTask(const LoopHandle loopHandle, const TaskHandle taskHandle)
190 {
191     LE_CHECK(loopHandle != NULL && taskHandle != NULL, return, "Invalid parameters");
192     LE_LOGV("LE_CloseTask %d", GetSocketFd(taskHandle));
193     BaseTask *task = (BaseTask *)taskHandle;
194     if (task->innerClose != NULL) {
195         task->innerClose(loopHandle, taskHandle);
196     }
197     free(task);
198 }
199 
LE_GetUserData(TaskHandle handle)200 void *LE_GetUserData(TaskHandle handle)
201 {
202     LE_CHECK(handle != NULL, return NULL, "Invalid handle");
203     BaseTask *stream = (BaseTask *)handle;
204     return (void *)(((char *)stream) + stream->userDataOffset);
205 }
206 
LE_GetSendResult(const BufferHandle handle)207 int32_t LE_GetSendResult(const BufferHandle handle)
208 {
209     LE_CHECK(handle != NULL, return 0, "Invalid handle");
210     return ((LE_Buffer *)handle)->result;
211 }