• 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_signal.h"
17 
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/signalfd.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include "le_loop.h"
26 #include "le_task.h"
27 #include "loop_event.h"
28 
HandleSignalEvent_(const LoopHandle loop,const TaskHandle task,uint32_t oper)29 static LE_STATUS HandleSignalEvent_(const LoopHandle loop, const TaskHandle task, uint32_t oper)
30 {
31     if (!LE_TEST_FLAGS(oper, Event_Read)) {
32         return LE_FAILURE;
33     }
34     struct signalfd_siginfo fdsi;
35     ssize_t s = read(GetSocketFd(task), &fdsi, sizeof(fdsi));
36     LE_CHECK(s == sizeof(fdsi), return LE_FAILURE, "Failed to read sign");
37     SignalTask *sigTask = (SignalTask *)task;
38     if (sigTask->processSignal) {
39         sigTask->processSignal(&fdsi);
40     }
41     return LE_SUCCESS;
42 }
43 
HandleSignalTaskClose_(const LoopHandle loopHandle,const TaskHandle signalHandle)44 static void HandleSignalTaskClose_(const LoopHandle loopHandle, const TaskHandle signalHandle)
45 {
46     BaseTask *task = (BaseTask *)signalHandle;
47     CloseTask(loopHandle, task);
48     close(task->taskId.fd);
49 }
50 
LE_CreateSignalTask(const LoopHandle loopHandle,SignalHandle * signalHandle,LE_ProcessSignal processSignal)51 LE_STATUS LE_CreateSignalTask(const LoopHandle loopHandle, SignalHandle *signalHandle, LE_ProcessSignal processSignal)
52 {
53     LE_CHECK(loopHandle != NULL && signalHandle != NULL, return LE_INVALID_PARAM, "Invalid parameters");
54     LE_CHECK(processSignal != NULL, return LE_FAILURE, "Invalid parameters processSignal");
55     sigset_t mask;
56     sigemptyset(&mask);
57     int sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
58     LE_CHECK(sfd > 0, return -1, "Failed to create signal fd");
59     LE_BaseInfo info = {TASK_SIGNAL, NULL};
60     SignalTask *task = (SignalTask *)CreateTask(loopHandle, sfd, &info, sizeof(SignalTask));
61     LE_CHECK(task != NULL, return LE_NO_MEMORY, "Failed to create task");
62     task->base.handleEvent = HandleSignalEvent_;
63     task->base.innerClose = HandleSignalTaskClose_;
64     task->sigNumber = 0;
65     sigemptyset(&task->mask);
66     task->processSignal = processSignal;
67     *signalHandle = (SignalHandle)task;
68     return LE_SUCCESS;
69 }
70 
LE_AddSignal(const LoopHandle loopHandle,const SignalHandle signalHandle,int signal)71 LE_STATUS LE_AddSignal(const LoopHandle loopHandle, const SignalHandle signalHandle, int signal)
72 {
73     LE_CHECK(loopHandle != NULL && signalHandle != NULL, return LE_INVALID_PARAM, "Invalid parameters");
74     EventLoop *loop = (EventLoop *)loopHandle;
75     SignalTask *task = (SignalTask *)signalHandle;
76     LE_LOGI("LE_AddSignal %d %d", signal, task->sigNumber);
77     if (sigismember(&task->mask, signal)) {
78         return LE_SUCCESS;
79     }
80     sigaddset(&task->mask, signal);
81     sigprocmask(SIG_BLOCK, &task->mask, NULL);
82     int sfd = signalfd(GetSocketFd(signalHandle), &task->mask, SFD_NONBLOCK | SFD_CLOEXEC);
83     LE_CHECK(sfd > 0, return -1, "Failed to create signal fd");
84     if (task->sigNumber == 0) {
85         loop->addEvent(loop, (const BaseTask *)task, Event_Read);
86     } else {
87         loop->modEvent(loop, (const BaseTask *)task, Event_Read);
88     }
89     task->sigNumber++;
90     return LE_SUCCESS;
91 }
92 
LE_RemoveSignal(const LoopHandle loopHandle,const SignalHandle signalHandle,int signal)93 LE_STATUS LE_RemoveSignal(const LoopHandle loopHandle, const SignalHandle signalHandle, int signal)
94 {
95     LE_CHECK(loopHandle != NULL && signalHandle != NULL, return LE_INVALID_PARAM, "Invalid parameters");
96     EventLoop *loop = (EventLoop *)loopHandle;
97     SignalTask *task = (SignalTask *)signalHandle;
98     LE_LOGI("LE_RemoveSignal %d %d", signal, task->sigNumber);
99     if (!sigismember(&task->mask, signal)) {
100         return LE_SUCCESS;
101     }
102     sigdelset(&task->mask, signal);
103     task->sigNumber--;
104     int sfd = signalfd(GetSocketFd(signalHandle), &task->mask, SFD_NONBLOCK | SFD_CLOEXEC);
105     LE_CHECK(sfd > 0, return -1, "Failed to create signal fd");
106     if (task->sigNumber <= 0) {
107         loop->delEvent(loop, GetSocketFd(signalHandle), Event_Read);
108     }
109     return LE_SUCCESS;
110 }
111 
LE_CloseSignalTask(const LoopHandle loopHandle,const SignalHandle signalHandle)112 void LE_CloseSignalTask(const LoopHandle loopHandle, const SignalHandle signalHandle)
113 {
114     LE_CHECK(loopHandle != NULL && signalHandle != NULL, return, "Invalid parameters");
115     LE_CloseTask(loopHandle, signalHandle);
116 }
117