source: xplcommon/src/xplcommon/POSIXWaiter.cc@ 1:00e7af4d1367

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

Implemented basic event waiting infrastructure

File size: 4.9 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 "config.h"
33#ifdef HAVE_POLL_H
34
35//------------------------------------------------------------------------------
36
37#include "POSIXWaiter.h"
38#include "POSIXWaitable.h"
39
40#include <cassert>
41#include <cstdio>
42
43//------------------------------------------------------------------------------
44
45using xplcommon::POSIXWaiter;
46
47//------------------------------------------------------------------------------
48
49inline bool POSIXWaiter::hasReady() const
50{
51 for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
52 ++i)
53 {
54 POSIXWaitable* waitable = i->second;
55 if (waitable->ready()) return true;
56 }
57 return false;
58}
59
60//------------------------------------------------------------------------------
61
62inline size_t POSIXWaiter::setupPollFDs(pollfd* pollFDs)
63{
64 size_t numValid = 0;
65
66 for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
67 ++i)
68 {
69 POSIXWaitable* waitable = i->second;
70 if (waitable->events==0) continue;
71
72 pollfd& pollFD = pollFDs[numValid++];
73
74 pollFD.fd = waitable->fd;
75 pollFD.events = waitable->events;
76 pollFD.revents = 0;
77 }
78
79 return numValid;
80}
81
82//------------------------------------------------------------------------------
83
84inline void POSIXWaiter::processPollFDs(const pollfd* pollFDs, size_t size)
85{
86 for(size_t i = 0; i<size; ++i) {
87 const pollfd& pollFD = pollFDs[i];
88 if (pollFD.revents!=0) {
89 waitables_t::iterator j = waitables.find(pollFD.fd);
90 assert(j!=waitables.end());
91 POSIXWaitable* waitable = j->second;
92 waitable->handleEvents(pollFD.revents);
93 }
94 }
95}
96
97//------------------------------------------------------------------------------
98
99POSIXWaiter::~POSIXWaiter()
100{
101 for(waitables_t::iterator i = waitables.begin(); i!=waitables.end(); ++i)
102 {
103 POSIXWaitable* waitable = i->second;
104 waitable->waiter = 0;
105 }
106}
107
108//------------------------------------------------------------------------------
109
110bool POSIXWaiter::wait(int timeout)
111{
112 if (hasReady()) return true;
113
114 pollfd pollFDs[numWaitables];
115 size_t numValid = setupPollFDs(pollFDs);
116
117 int result = poll(pollFDs, numValid, timeout);
118
119 if (result<0) {
120 perror("POSIXWaiter::wait: poll");
121 return false;
122 } else if (result>0) {
123 processPollFDs(pollFDs, numValid);
124 }
125
126 return hasReady();
127}
128
129//------------------------------------------------------------------------------
130
131void POSIXWaiter::add(POSIXWaitable* waitable)
132{
133 assert(waitable->fd>=0);
134 assert(waitables.find(waitable->fd)==waitables.end());
135 waitables[waitable->fd] = waitable;
136 ++numWaitables;
137}
138
139//------------------------------------------------------------------------------
140
141void POSIXWaiter::remove(POSIXWaitable* waitable)
142{
143 assert(numWaitables>0);
144 assert(waitables.find(waitable->fd)!=waitables.end());
145 assert(waitables[waitable->fd]==waitable);
146 waitables.erase(waitable->fd);
147 --numWaitables;
148}
149
150
151//------------------------------------------------------------------------------
152#endif // HAVE_POLL_H
153
154// Local Variables:
155// mode: C++
156// c-basic-offset: 4
157// indent-tabs-mode: nil
158// End:
Note: See TracBrowser for help on using the repository browser.