source: xplcommon/src/xplcommon/posix/Waiter.cc@ 29:54c2d451f8a0

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

Implemented a blocking stream and a corresponding trst program

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