Add first version
[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 #include "private/redis/hiredisepolladapter.hpp"
18 #include <sys/epoll.h>
19 #include "private/engine.hpp"
20 #include "private/redis/hiredissystem.hpp"
21
22 using namespace shareddatalayer;
23 using namespace shareddatalayer::redis;
24
25
26 namespace
27 {
28     void addReadWrap(void* data)
29     {
30         auto instance(static_cast<HiredisEpollAdapter*>(data));
31         instance->addRead();
32     }
33
34     void delReadWrap(void* data)
35     {
36         auto instance(static_cast<HiredisEpollAdapter*>(data));
37         instance->delRead();
38     }
39
40     void addWriteWrap(void* data)
41     {
42         auto instance(static_cast<HiredisEpollAdapter*>(data));
43         instance->addWrite();
44     }
45
46     void delWriteWrap(void* data)
47     {
48         auto instance(static_cast<HiredisEpollAdapter*>(data));
49         instance->delWrite();
50     }
51
52     void cleanUpWrap(void* data)
53     {
54         auto instance(static_cast<HiredisEpollAdapter*>(data));
55         instance->cleanUp();
56     }
57 }
58
59 HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine):
60     HiredisEpollAdapter(engine, HiredisSystem::getHiredisSystem())
61 {
62 }
63
64 HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine, HiredisSystem& hiredisSystem):
65     engine(engine),
66     hiredisSystem(hiredisSystem),
67     ac(nullptr),
68     eventState(0),
69     reading(false),
70     writing(false),
71     isMonitoring(false)
72 {
73 }
74
75 HiredisEpollAdapter::~HiredisEpollAdapter()
76 {
77     if (ac && isMonitoring)
78         cleanUp();
79 }
80
81 void HiredisEpollAdapter::attach(redisAsyncContext* ac)
82 {
83     eventState = 0;
84     reading = false;
85     writing = false;
86     this->ac = ac;
87     this->ac->ev.data = this;
88     this->ac->ev.addRead = addReadWrap;
89     this->ac->ev.delRead = delReadWrap;
90     this->ac->ev.addWrite = addWriteWrap;
91     this->ac->ev.delWrite = delWriteWrap;
92     this->ac->ev.cleanup = cleanUpWrap;
93     engine.addMonitoredFD(ac->c.fd,
94                           eventState,
95                           std::bind(&HiredisEpollAdapter::eventHandler,
96                                     this,
97                                     std::placeholders::_1));
98     isMonitoring = true;
99 }
100
101 void HiredisEpollAdapter::eventHandler(unsigned int events)
102 {
103     if (events & Engine::EVENT_IN)
104         if (reading)
105             hiredisSystem.redisAsyncHandleRead(ac);
106     if (events & Engine::EVENT_OUT)
107         if (writing)
108             hiredisSystem.redisAsyncHandleWrite(ac);
109 }
110
111 void HiredisEpollAdapter::addRead()
112 {
113     if (reading)
114         return;
115     reading = true;
116     eventState |= Engine::EVENT_IN;
117     engine.modifyMonitoredFD(ac->c.fd, eventState);
118 }
119
120 void HiredisEpollAdapter::delRead()
121 {
122     reading = false;
123     eventState &= ~Engine::EVENT_IN;
124     engine.modifyMonitoredFD(ac->c.fd, eventState);
125 }
126
127 void HiredisEpollAdapter::addWrite()
128 {
129     if (writing)
130         return;
131     writing = true;
132     eventState |= Engine::EVENT_OUT;
133     engine.modifyMonitoredFD(ac->c.fd, eventState);
134 }
135
136 void HiredisEpollAdapter::delWrite()
137 {
138     writing = false;
139     eventState &= ~Engine::EVENT_OUT;
140     engine.modifyMonitoredFD(ac->c.fd, eventState);
141 }
142
143 void HiredisEpollAdapter::cleanUp()
144 {
145     reading = false;
146     writing = false;
147     eventState = 0;
148     engine.deleteMonitoredFD(ac->c.fd);
149     isMonitoring = false;
150 }