2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 * @file descriptor-set.cpp
18 * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
22 #include "descriptor-set.h"
23 #include <dpl/errno_string.h>
24 #include <dpl/log/log.h>
30 DescriptorSet::DescriptorSet() : m_dirty(true), m_fds(NULL) {
33 DescriptorSet::~DescriptorSet() {
37 void DescriptorSet::purge() {
38 for(auto it:m_descriptors)
40 m_descriptors.clear();
43 void DescriptorSet::add(int fd, short events, Callback&& callback) {
44 // map operator[] requires empty DescriptorData constructor
45 auto it = m_descriptors.find(fd);
46 if (it == m_descriptors.end()) {
47 m_descriptors.insert(std::make_pair(fd,DescriptorData(events, std::move(callback))));
49 it->second.events = events;
50 it->second.callback = std::move(callback);
55 void DescriptorSet::remove(int fd, bool close_fd) {
56 if (0 != m_descriptors.erase(fd)) {
63 void DescriptorSet::wait(int timeout_ms) {
68 int ret = TEMP_FAILURE_RETRY(poll(m_fds, m_descriptors.size(), timeout_ms));
70 ThrowMsg(Timeout, "Poll timeout");
73 ThrowMsg(InternalError, "Poll failed " << GetErrnoString(err));
79 bool DescriptorSet::rebuildPollfd() {
83 if (m_descriptors.empty()) {
84 LogWarning("Nothing to wait for");
88 m_fds = new pollfd[m_descriptors.size()];
90 for(const auto& it : m_descriptors) {
91 m_fds[idx].fd = it.first;
92 m_fds[idx].events = it.second.events;
100 void DescriptorSet::notify(int descCount) {
101 size_t size = m_descriptors.size();
102 for(size_t idx = 0;idx < size;++idx) {
103 const pollfd& pfd = m_fds[idx];
104 if (pfd.revents == 0)
108 * Descriptors can be added/removed inside observer callback but:
109 * 1. m_fds is not affected. It will be regenerated in next wait()
110 * 2. No m_descriptors iterator will be invalidated
111 * 3. m_descriptors size is stored in local variable
113 m_descriptors.at(pfd.fd).callback(pfd.fd, pfd.revents);
116 // no more descriptors to check
121 ThrowMsg(InternalError, "Number of notified descriptors do not match");
124 } /* namespace CKM */