c2529b8cfa0455dfce113de243d6e6c4799294a8
[ric-plt/sdl.git] / src / redis / hiredisepolladapter.cpp
1 /*
2    Copyright (c) 2018-2019 Nokia.
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 */
16
17 /*
18  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
19  * platform project (RICP).
20 */
21
22 #include "private/redis/hiredisepolladapter.hpp"
23 #include <sys/epoll.h>
24 #include "private/engine.hpp"
25 #include "private/redis/hiredissystem.hpp"
26
27 using namespace shareddatalayer;
28 using namespace shareddatalayer::redis;
29
30
31 namespace
32 {
33     void addReadWrap(void* data)
34     {
35         auto instance(static_cast<HiredisEpollAdapter*>(data));
36         instance->addRead();
37     }
38
39     void delReadWrap(void* data)
40     {
41         auto instance(static_cast<HiredisEpollAdapter*>(data));
42         instance->delRead();
43     }
44
45     void addWriteWrap(void* data)
46     {
47         auto instance(static_cast<HiredisEpollAdapter*>(data));
48         instance->addWrite();
49     }
50
51     void delWriteWrap(void* data)
52     {
53         auto instance(static_cast<HiredisEpollAdapter*>(data));
54         instance->delWrite();
55     }
56
57     void cleanUpWrap(void* data)
58     {
59         auto instance(static_cast<HiredisEpollAdapter*>(data));
60         instance->cleanUp();
61     }
62 }
63
64 HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine):
65     HiredisEpollAdapter(engine, HiredisSystem::getHiredisSystem())
66 {
67 }
68
69 HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine, HiredisSystem& hiredisSystem):
70     engine(engine),
71     hiredisSystem(hiredisSystem),
72     ac(nullptr),
73     eventState(0),
74     reading(false),
75     writing(false),
76     isMonitoring(false)
77 {
78 }
79
80 HiredisEpollAdapter::~HiredisEpollAdapter()
81 {
82     if (ac && isMonitoring)
83         cleanUp();
84 }
85
86 void HiredisEpollAdapter::attach(redisAsyncContext* ac)
87 {
88     eventState = 0;
89     reading = false;
90     writing = false;
91     this->ac = ac;
92     this->ac->ev.data = this;
93     this->ac->ev.addRead = addReadWrap;
94     this->ac->ev.delRead = delReadWrap;
95     this->ac->ev.addWrite = addWriteWrap;
96     this->ac->ev.delWrite = delWriteWrap;
97     this->ac->ev.cleanup = cleanUpWrap;
98     engine.addMonitoredFD(ac->c.fd,
99                           eventState,
100                           std::bind(&HiredisEpollAdapter::eventHandler,
101                                     this,
102                                     std::placeholders::_1));
103     isMonitoring = true;
104 }
105
106 void HiredisEpollAdapter::eventHandler(unsigned int events)
107 {
108     if (events & Engine::EVENT_IN)
109         if (reading)
110             hiredisSystem.redisAsyncHandleRead(ac);
111     if (events & Engine::EVENT_OUT)
112         if (writing)
113             hiredisSystem.redisAsyncHandleWrite(ac);
114 }
115
116 void HiredisEpollAdapter::addRead()
117 {
118     if (reading)
119         return;
120     reading = true;
121     eventState |= Engine::EVENT_IN;
122     engine.modifyMonitoredFD(ac->c.fd, eventState);
123 }
124
125 void HiredisEpollAdapter::delRead()
126 {
127     reading = false;
128     eventState &= ~Engine::EVENT_IN;
129     engine.modifyMonitoredFD(ac->c.fd, eventState);
130 }
131
132 void HiredisEpollAdapter::addWrite()
133 {
134     if (writing)
135         return;
136     writing = true;
137     eventState |= Engine::EVENT_OUT;
138     engine.modifyMonitoredFD(ac->c.fd, eventState);
139 }
140
141 void HiredisEpollAdapter::delWrite()
142 {
143     writing = false;
144     eventState &= ~Engine::EVENT_OUT;
145     engine.modifyMonitoredFD(ac->c.fd, eventState);
146 }
147
148 void HiredisEpollAdapter::cleanUp()
149 {
150     reading = false;
151     writing = false;
152     eventState = 0;
153     engine.deleteMonitoredFD(ac->c.fd);
154     isMonitoring = false;
155 }