1 karl 1.38 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.30 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.23 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.30 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.35 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.38 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.6 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.2 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.38 //
|
21 kumpf 1.6 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.6 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.2 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
|
34 david.dillard 1.36 // Modified By: Amit Arora (amita@in.ibm.com) for Bug#1170
35 // Sushma Fernandes (sushma@hp.com) for Bug#2057
|
36 joyce.j 1.31 // Josephine Eskaline Joyce (jojustin@in.ibm.com) for PEP#101
|
37 david.dillard 1.36 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
38 // David Dillard, Symantec Corp. (david_dillard@symantec.com)
|
39 mike 1.2 //
40 //%/////////////////////////////////////////////////////////////////////////////
41
|
42 david.dillard 1.36 #ifndef Pegasus_Monitor_h
43 #define Pegasus_Monitor_h
|
44 mike 1.2
45 #include <Pegasus/Common/Config.h>
|
46 kumpf 1.12 #include <Pegasus/Common/ArrayInternal.h>
|
47 mike 1.2 #include <Pegasus/Common/String.h>
48 #include <Pegasus/Common/Message.h>
|
49 mday 1.4 #include <Pegasus/Common/ModuleController.h>
|
50 kumpf 1.33 #include <Pegasus/Common/Socket.h>
|
51 mday 1.16 #include <Pegasus/Common/Sharable.h>
|
52 david.dillard 1.36 #include <Pegasus/Common/Linkage.h>
|
53 joyce.j 1.31 #include <Pegasus/Common/AutoPtr.h>
|
54 mike 1.2
55 PEGASUS_NAMESPACE_BEGIN
56
|
57 mday 1.13 class PEGASUS_COMMON_LINKAGE _MonitorEntry
|
58 mike 1.2 {
|
59 mday 1.15 public:
|
60 mike 1.39 SocketHandle socket;
|
61 mday 1.15 Uint32 queueId;
62 AtomicInt _status;
|
63 mike 1.37
64 // This copy constructor is inecessary since AtomicInt does not support
65 // copy construction.
66 _MonitorEntry(const _MonitorEntry& x) :
67 socket(x.socket),
68 queueId(x.queueId),
69 _status(x._status.get()),
70 _type(x._type)
71 {
72 }
|
73 mday 1.15 int _type;
|
74 david.dillard 1.36
|
75 mike 1.39 _MonitorEntry(SocketHandle sock, Uint32 q, int Type)
|
76 mday 1.15 : socket(sock), queueId(q), _status(EMPTY), _type(Type)
77 {
78 }
|
79 keith.petley 1.14
|
80 mday 1.15 _MonitorEntry() : socket(0), queueId(0), _status(EMPTY), _type(0)
81 {
82 }
|
83 david.dillard 1.36
|
84 mday 1.15 _MonitorEntry & operator =(const _MonitorEntry & entry)
85 {
86 if( this != &entry )
87 {
88 this->socket = entry.socket;
89 this->queueId = entry.queueId;
|
90 mike 1.37 this->_status = entry._status.get();
|
91 mday 1.15 this->_type = entry._type;
|
92 mday 1.10 }
|
93 david.dillard 1.36
|
94 mday 1.15 return *this;
95 }
|
96 david.dillard 1.36
97 enum entry_status
|
98 mday 1.15 {
99 IDLE,
100 BUSY,
101 DYING,
102 EMPTY
103 };
|
104 mike 1.2 };
105
106 /** This message occurs when there is activity on a socket. */
107 class SocketMessage : public Message
108 {
109 public:
110
|
111 mday 1.15 enum Events { READ = 1, WRITE = 2, EXCEPTION = 4 };
|
112 mike 1.2
|
113 david.dillard 1.36
|
114 mike 1.39 SocketMessage(SocketHandle socket_, Uint32 events_) :
|
115 mday 1.15 Message(SOCKET_MESSAGE), socket(socket_), events(events_)
116 {
117 }
|
118 mike 1.2
|
119 mike 1.39 SocketHandle socket;
|
120 mday 1.15 Uint32 events;
|
121 mike 1.2 };
122
123 /** This class monitors system-level events and notifies its clients of these
124 events by posting messages to their queues.
125
126 The monitor generates following message types:
127
128 <ul>
|
129 mday 1.15 <li> SocketMessage - occurs when activity on a socket </li>
|
130 mike 1.2 </ul>
131
132 Clients solicit these messages by calling one of the following methods:
133
134 <ul>
|
135 mday 1.15 <li> solicitSocketMessages() </li>
|
136 mike 1.2 </ul>
137
138 The following example shows how to solicit socket messages:
139
140 <pre>
|
141 mday 1.15 Monitor monitor;
142 Sint32 socket;
143 Uint32 queueId;
|
144 mike 1.2
|
145 mday 1.4
|
146 mday 1.15 ...
|
147 mike 1.2
|
148 mday 1.15 monitor.solicitSocketMessages(
|
149 david.dillard 1.36 socket,
150 SocketMessage::READ | SocketMessage::WRITE,
|
151 mday 1.15 queueId);
|
152 mike 1.2 </pre>
153
154 Each time activity occurs on the given socket, a SocketMessage is
155 enqueued on the given queue.
156
157 In order the monitor to generate messages, it must be run by calling
158 the run() method as shown below:
159
160 <pre>
|
161 mday 1.15 Monitor monitor;
|
162 mike 1.2
|
163 mday 1.15 ...
|
164 mike 1.2
|
165 mday 1.15 Uint32 milliseconds = 5000;
166 monitor.run(milliseconds);
|
167 mike 1.2 </pre>
168
169 In this example, the monitor is run for five seconds. The run method
170 returns after the first message is occurs or five seconds has transpired
171 (whichever occurs first).
172 */
173 class PEGASUS_COMMON_LINKAGE Monitor
174 {
|
175 mday 1.15 public:
|
176 david.dillard 1.36 enum Type
|
177 mday 1.15 {
|
178 a.arora 1.27 UNTYPED, ACCEPTOR, CONNECTOR, CONNECTION, INTERNAL
|
179 mday 1.15 };
|
180 david.dillard 1.36
181
|
182 mday 1.15 /** Default constructor. */
183 Monitor();
|
184 mike 1.2
|
185 mday 1.15 /** This destruct deletes all handlers which were installed. */
186 ~Monitor();
|
187 mike 1.2
|
188 sushma.fernandes 1.29 /** Sets the state of the monitor entry to the specified state.
189 This is used to synchronize the monitor and the worker
190 thread. Bug# 2057 */
191 void setState( Uint32 index, _MonitorEntry::entry_status status );
192
|
193 a.arora 1.27 void initializeTickler();
|
194 thilo.boehm 1.44 void uninitializeTickler();
195
|
196 a.arora 1.27 void tickle();
|
197 mday 1.15 /** Monitor system-level for the given number of milliseconds. Post a
198 message to the corresponding queue when such an event occurs.
199 Return after the time has elapsed or a single event has occurred,
200 whichever occurs first.
201
202 @param timeoutMsec the number of milliseconds to wait for an event.
203 @return true if an event occured.
204 */
|
205 kumpf 1.43 void run(Uint32 timeoutMsec);
|
206 mday 1.15
|
207 david.dillard 1.36 /** Solicit interest in SocketMessages. Note that there may only
|
208 mday 1.15 be one solicitor per socket.
209
210 @param socket the socket to monitor for activity.
211 @param events socket events to monitor (see the SocketMessage::Events
212 enumeration for details).
213 @param queueId of queue on which to post socket messages.
214 @return false if messages have already been solicited on this socket.
215 */
216 int solicitSocketMessages(
|
217 mike 1.39 SocketHandle socket,
|
218 david.dillard 1.36 Uint32 events,
219 Uint32 queueId,
220 int type);
|
221 mday 1.15
222 /** Unsolicit messages on the given socket.
223
224 @param socket on which to unsolicit messages.
225 @return false if no such solicitation has been made on the given socket.
226 */
|
227 mike 1.39 void unsolicitSocketMessages(SocketHandle);
|
228 mday 1.15
|
229 david.dillard 1.36 /** dispatch a message to the cimom on an independent thread
|
230 kumpf 1.24 Note: The Monitor class uses the MessageQueueService ThreadPool.
231 This ThreadPool is only available if it has been initialized by
232 the MessageQueueService. Therefore, the Monitor class should
233 only be used when the MessageQueueService is active in the
234 system.
|
235 mday 1.15 */
|
236 mike 1.42 static ThreadReturnType PEGASUS_THREAD_CDECL _dispatch(void *);
|
237 david.dillard 1.36
238 /** stop listening for client connections
|
239 kumpf 1.18 */
|
240 chuck 1.28 void stopListeningForConnections(Boolean wait);
|
241 kumpf 1.18
|
242 mike 1.2 private:
|
243 david.dillard 1.36
|
244 mday 1.15 Array<_MonitorEntry> _entries;
245 Mutex _entry_mut;
|
246 kumpf 1.18 AtomicInt _stopConnections;
|
247 a.arora 1.27 Semaphore _stopConnectionsSem;
248 Uint32 _solicitSocketCount; // tracks how many times solicitSocketCount() has been called
|
249 mday 1.15 friend class HTTPConnection;
|
250 a.arora 1.27 struct sockaddr_in _tickle_server_addr;
251 struct sockaddr_in _tickle_client_addr;
252 struct sockaddr_in _tickle_peer_addr;
|
253 mike 1.39 SocketHandle _tickle_client_socket;
254 SocketHandle _tickle_server_socket;
255 SocketHandle _tickle_peer_socket;
|
256 sushma.fernandes 1.29 Mutex _tickle_mutex;
|
257 mike 1.2 };
|
258 mday 1.15
|
259 mike 1.2 PEGASUS_NAMESPACE_END
260
261 #endif /* Pegasus_Monitor_h */
|