source: xplcommon/src/xplcommon/posix/Waiter.cc@ 14:3caa1d3122db

Last change on this file since 14:3caa1d3122db was 14:3caa1d3122db, checked in by István Váradi <ivaradi@…>, 11 years ago

Moved the storage of the error code to where it belongs

File size: 4.7 KB
Line 
1// Copyright (c) 2012 by István Váradi
2
3// This file is part of libxplcommon, a common utility library for
4// development related to X-Plane
5
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8
9// 1. Redistributions of source code must retain the above copyright notice, this
10// list of conditions and the following disclaimer.
11// 2. Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
13// and/or other materials provided with the distribution.
14
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26// The views and conclusions contained in the software and documentation are those
27// of the authors and should not be interpreted as representing official policies,
28// either expressed or implied, of the FreeBSD Project.
29
30//------------------------------------------------------------------------------
31
32#include "Waiter.h"
33
34#include "Waitable.h"
35
36#include <cassert>
37#include <cerrno>
38
39//------------------------------------------------------------------------------
40
41using xplcommon::posix::Waiter;
42
43//------------------------------------------------------------------------------
44
45inline bool Waiter::hasReady() const
46{
47 for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
48 ++i)
49 {
50 Waitable* waitable = i->second;
51 if (waitable->ready()) return true;
52 }
53 return false;
54}
55
56//------------------------------------------------------------------------------
57
58inline size_t Waiter::setupPollFDs(pollfd* pollFDs)
59{
60 size_t numValid = 0;
61
62 for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
63 ++i)
64 {
65 Waitable* waitable = i->second;
66 if (waitable->events==0) continue;
67
68 pollfd& pollFD = pollFDs[numValid++];
69
70 pollFD.fd = waitable->fd;
71 pollFD.events = waitable->events;
72 pollFD.revents = 0;
73 }
74
75 return numValid;
76}
77
78//------------------------------------------------------------------------------
79
80inline void Waiter::processPollFDs(const pollfd* pollFDs, size_t size)
81{
82 for(size_t i = 0; i<size; ++i) {
83 const pollfd& pollFD = pollFDs[i];
84 if (pollFD.revents!=0) {
85 waitables_t::iterator j = waitables.find(pollFD.fd);
86 assert(j!=waitables.end());
87 Waitable* waitable = j->second;
88 waitable->handleEvents(pollFD.revents);
89 }
90 }
91}
92
93//------------------------------------------------------------------------------
94
95Waiter::~Waiter()
96{
97 for(waitables_t::iterator i = waitables.begin(); i!=waitables.end(); ++i)
98 {
99 Waitable* waitable = i->second;
100 waitable->waiter = 0;
101 }
102}
103
104//------------------------------------------------------------------------------
105
106bool Waiter::wait(int timeout)
107{
108 if (hasReady()) return true;
109
110 pollfd pollFDs[numWaitables];
111 size_t numValid = setupPollFDs(pollFDs);
112
113 int result = poll(pollFDs, numValid, timeout);
114
115 if (result<0) {
116 setErrorCode(errno);
117 return false;
118 } else if (result>0) {
119 processPollFDs(pollFDs, numValid);
120 }
121
122 return hasReady();
123}
124
125//------------------------------------------------------------------------------
126
127void Waiter::add(Waitable* waitable)
128{
129 assert(waitable->fd>=0);
130 assert(waitables.find(waitable->fd)==waitables.end());
131 waitables[waitable->fd] = waitable;
132 ++numWaitables;
133}
134
135//------------------------------------------------------------------------------
136
137void Waiter::remove(Waitable* waitable)
138{
139 assert(numWaitables>0);
140 assert(waitables.find(waitable->fd)!=waitables.end());
141 assert(waitables[waitable->fd]==waitable);
142 waitables.erase(waitable->fd);
143 --numWaitables;
144}
145
146
147//------------------------------------------------------------------------------
148
149// Local Variables:
150// mode: C++
151// c-basic-offset: 4
152// indent-tabs-mode: nil
153// End:
Note: See TracBrowser for help on using the repository browser.