Additional adjustments for Poller
[libs/core.git] / source / io / poll.cpp
1 #include <stdexcept>
2 #include "eventobject.h"
3 #include "poll.h"
4 #include "poll_platform.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace IO {
10
11 Poller::Poller():
12         priv(new Private),
13         events_changed(false),
14         objs_changed(false)
15 { }
16
17 Poller::~Poller()
18 {
19         delete priv;
20 }
21
22 void Poller::set_object(EventObject &obj, PollEvent ev)
23 {
24         // Verify that the object has an event handle
25         if(ev)
26                 obj.get_event_handle();
27
28         for(vector<PolledObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
29                 if(i->object==&obj)
30                 {
31                         if(ev)
32                                 i->events = ev;
33                         else
34                         {
35                                 *i = objects.back();
36                                 objects.pop_back();
37                                 objs_changed = true;
38                         }
39                         events_changed = true;
40                         return;
41                 }
42
43         if(!ev)
44                 return;
45
46 #ifdef _WIN32
47         if(objects.size()>=MAXIMUM_WAIT_OBJECTS)
48                 throw logic_error("Maximum number of wait objects reached");
49 #endif
50
51         objects.push_back(PolledObject(&obj, ev));
52         objs_changed = true;
53 }
54
55 unsigned Poller::poll()
56 {
57         return do_poll(-1);
58 }
59
60 unsigned Poller::poll(const Time::TimeDelta &timeout)
61 {
62         if(timeout<Time::zero)
63                 throw invalid_argument("Poller::poll");
64
65         return do_poll(static_cast<int>(timeout/Time::msec));
66 }
67
68 unsigned Poller::do_poll(int timeout)
69 {
70         if(objs_changed || events_changed)
71         {
72                 rebuild_array();
73                 events_changed = false;
74                 objs_changed = false;
75         }
76
77         poll_result.clear();
78
79         platform_poll(timeout);
80
81         return poll_result.size();
82 }
83
84
85 PollEvent platform_poll(EventObject &, PollEvent, int);
86
87 PollEvent poll(EventObject &obj, PollEvent pe)
88 {
89         return platform_poll(obj, pe, -1);
90 }
91
92 PollEvent poll(EventObject &obj, PollEvent pe, const Time::TimeDelta &timeout)
93 {
94         if(timeout<Time::zero)
95                 throw invalid_argument("poll");
96
97         return platform_poll(obj, pe, static_cast<int>(timeout/Time::msec));
98 }
99
100 } // namespace IO
101 } // namespace Msp