1 #ifndef Poller_poll_H
2 #define Poller_poll_H
3 /*--------------------------------------------------------------------------
4  Copyright 1999,2000, Dan Kegel http://www.kegel.com/
5  See the file COPYING
6  (Also freely licensed to Disappearing, Inc. under a separate license
7  which allows them to do absolutely anything they want with it, without
8  regard to the GPL.)
9 
10  This module is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14 
15  This module is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 --------------------------------------------------------------------------*/
24 #include <assert.h>
25 #include <errno.h>
26 #include <sys/poll.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include "Poller.h"
30 
31 /**
32  * A class to monitor a set of file descriptors for readiness events.
33  * Current an efficient wrapper around the poll() system call.
34  * This is the code you would have written yourself if you had had the time...
35  */
36 class Poller_poll : public Poller {
37 public:
38 	/// Initialize the Poller.
39 	int init();
40 
41 	/// Release any resouces allocated internally by this Poller.
42 	void shutdown();
43 
44 	/**
45 	 Add a file descriptor to the set we monitor.
46 	 @param fd file descriptor to add
47 	 @param client object to handle events for this fd.  May use same client with more than one fd.
48 	 @param eventmask initial event mask for this fd
49 	 */
50 	int add(int fd, Client *client, short eventmask);
51 
52 	/// Remove a file descriptor
53 	int del(int fd);
54 
55 	/// Give a new value for the given file descriptor's eventmask.
56 	int setMask(int fd, short eventmask);
57 
58 	/// Set fd's eventmask to its present value OR'd with the given one
59 	int orMask(int fd, short eventmask);
60 
61 	/// Set fd's eventmask to its present value AND'd with the given one
62 	int andMask(int fd, short eventmask);
63 
64 	/**
65 	 Sleep at most timeout_millisec waiting for an I/O readiness event
66 	 on the file descriptors we're watching.  Fills internal array
67 	 of readiness events.  Call getNextEvent() repeatedly to read its
68 	 contents.
69 	 @return 0 on success, EWOULDBLOCK if no events ready
70 	 */
71 	int waitForEvents(int timeout_millisec);
72 
73 	/**
74 	 Get the next event that was found by waitForEvents.
75 	 @return 0 on success, EWOULDBLOCK if no more events
76 	 */
77 	int getNextEvent(PollEvent *e);
78 
79 	/**
80 	 Sleep at most timeout_millisec waiting for an I/O readiness event
81 	 on the file descriptors we're watching, and dispatch events to
82 	 the handler for each file descriptor that is ready for I/O.
83 	 This is included as an example of how to use
84 	 waitForEvents and getNextEvent.  Real programs should probably
85 	 avoid waitAndDispatchEvents and call waitForEvents and getNextEvent
86 	 instead for maximum control over client deletion.
87 	 */
88 	int waitAndDispatchEvents(int timeout_millisec);
89 
90 private:
91 	/// 1 + maximum fd in monitored set = 1 + highest index used in m_fd2client[]
92 	int m_fd2client_used;
93 
94 	/// number of elements allocated in m_fd2client[]
95 	int m_fd2client_alloc;
96 
97 	/// Resizable array of pollfds to pass to poll().  Compact, no gaps.  Does not contain duplicate fd's.
98 	struct pollfd *m_pfds;
99 
100 	/// Resizable array of ptrs to event handlers, indexed by same index as m_pfds.  May contain duplicates.
101 	Client **m_clients;
102 
103 	/// Number of file descriptors monitored.  Also 1 + highest index used in m_pfds or m_clients
104 	int m_pfds_used;
105 
106 	/// number of elements allocated in m_pfds[]
107 	int m_pfds_alloc;
108 
109 	/// Resizable lookup table indexed by fd to find entry in m_pfds or m_clients
110 	int *m_fd2pfdnum;
111 
112 	/// number of events in m_pfds left after last call to getNextEvent()
113 	int m_rfds;
114 
115 	/// used by dispatchNextEvent to iterate downwards through the clients
116 	int m_cur_pfdnum;
117 
118 };
119 #endif
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133