IPC: Support older glib
[platform/core/security/vasum.git] / common / ipc / internals / request-queue.hpp
1 /*
2 *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 *  Contact: Jan Olszak <j.olszak@samsung.com>
5 *
6 *  Licensed under the Apache License, Version 2.0 (the "License");
7 *  you may not use this file except in compliance with the License.
8 *  You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License
17 */
18
19 /**
20  * @file
21  * @author  Jan Olszak (j.olszak@samsung.com)
22  * @brief   Managing the queue of messages carrying any kind of data
23  */
24
25 #ifndef COMMON_IPC_INTERNALS_MESSAGE_QUEUE_HPP
26 #define COMMON_IPC_INTERNALS_MESSAGE_QUEUE_HPP
27
28 #include "ipc/exception.hpp"
29 #include "ipc/internals/eventfd.hpp"
30 #include "logger/logger.hpp"
31
32 #include <list>
33 #include <memory>
34 #include <algorithm>
35
36 namespace vasum {
37 namespace ipc {
38
39 /**
40 * Class for managing a queue of Requests carrying any data
41 */
42 template<typename RequestIdType>
43 class RequestQueue {
44 public:
45     RequestQueue() = default;
46
47     RequestQueue(const RequestQueue&) = delete;
48     RequestQueue& operator=(const RequestQueue&) = delete;
49
50     struct Request {
51         Request(const Request& other) = delete;
52         Request& operator=(const Request&) = delete;
53
54         Request(Request&&) = default;
55         Request(const RequestIdType requestID, const std::shared_ptr<void>& data)
56             : requestID(requestID),
57               data(data)
58         {}
59
60         template<typename DataType>
61         std::shared_ptr<DataType> get()
62         {
63             return std::static_pointer_cast<DataType>(data);
64         }
65
66         RequestIdType requestID;
67         std::shared_ptr<void> data;
68     };
69
70     /**
71      * @return event's file descriptor
72      */
73     int getFD() const;
74
75     /**
76      * @return is the queue empty
77      */
78     bool isEmpty() const;
79
80     /**
81      * Push data to the queue
82      *
83      * @param requestID request type
84      * @param data data corresponding to the request
85      */
86     void push(const RequestIdType requestID,
87               const std::shared_ptr<void>& data = nullptr);
88
89     /**
90      * @return get the data from the next request
91      */
92     Request pop();
93
94     /**
95      * Remove elements from the queue when the predicate returns true
96      *
97      * @param predicate condition
98      * @return was anything removed
99      */
100     template<typename Predicate>
101     bool removeIf(Predicate predicate);
102
103 private:
104     std::list<Request> mRequests;
105     EventFD mEventFD;
106 };
107
108 template<typename RequestIdType>
109 int RequestQueue<RequestIdType>::getFD() const
110 {
111     return mEventFD.getFD();
112 }
113
114 template<typename RequestIdType>
115 bool RequestQueue<RequestIdType>::isEmpty() const
116 {
117     return mRequests.empty();
118 }
119
120 template<typename RequestIdType>
121 void RequestQueue<RequestIdType>::push(const RequestIdType requestID,
122                                        const std::shared_ptr<void>& data)
123 {
124     Request request(requestID, data);
125     mRequests.push_back(std::move(request));
126     mEventFD.send();
127 }
128
129 template<typename RequestIdType>
130 typename RequestQueue<RequestIdType>::Request RequestQueue<RequestIdType>::pop()
131 {
132     mEventFD.receive();
133     if (mRequests.empty()) {
134         LOGE("Request queue is empty");
135         throw IPCException("Request queue is empty");
136     }
137     Request request = std::move(mRequests.front());
138     mRequests.pop_front();
139     return request;
140 }
141
142 template<typename RequestIdType>
143 template<typename Predicate>
144 bool RequestQueue<RequestIdType>::removeIf(Predicate predicate)
145 {
146     auto it = std::find_if(mRequests.begin(), mRequests.end(), predicate);
147     if (it == mRequests.end()) {
148         return false;
149     }
150
151     do {
152         it = mRequests.erase(it);
153         it = std::find_if(it, mRequests.end(), predicate);
154     } while (it != mRequests.end());
155
156     return true;
157 }
158 } // namespace ipc
159 } // namespace vasum
160
161 #endif // COMMON_IPC_INTERNALS_MESSAGE_QUEUE_HPP