BOSS 7.0.6
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlRpcDispatch.cpp
Go to the documentation of this file.
1
2#include "XmlRpcDispatch.h"
3#include "XmlRpcSource.h"
4#include "XmlRpcUtil.h"
5
6#include <math.h>
7#include <sys/timeb.h>
8
9#if defined(_WINDOWS)
10# include <winsock2.h>
11
12# define USE_FTIME
13# if defined(_MSC_VER)
14# define timeb _timeb
15# define ftime _ftime
16# endif
17#else
18# include <sys/time.h>
19#endif // _WINDOWS
20
21#include <iostream>
22
23using namespace XmlRpc;
24
25
27{
28 _endTime = -1.0;
29 _doClear = false;
30 _inWork = false;
31}
32
33
35{
36}
37
38// Monitor this source for the specified events and call its event handler
39// when the event occurs
40void
42{
43 _sources.push_back(MonitoredSource(source, mask));
44}
45
46// Stop monitoring this source. Does not close the source.
47void
49{
50 for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
51 if (it->getSource() == source)
52 {
53 _sources.erase(it);
54 break;
55 }
56}
57
58
59// Modify the types of events to watch for on this source
60void
62{
63 for (SourceList::iterator it=_sources.begin(); it!=_sources.end(); ++it)
64 if (it->getSource() == source)
65 {
66 it->getMask() = eventMask;
67 break;
68 }
69}
70
71
72
73// Watch current set of sources and process events
74void
75XmlRpcDispatch::work(double timeout)
76{
77 // Compute end time
78 _endTime = (timeout < 0.0) ? -1.0 : (getTime() + timeout);
79 _doClear = false;
80 _inWork = true;
81
82 // Only work while there is something to monitor
83 while (_sources.size() > 0) {
84
85 // Construct the sets of descriptors we are interested in
86 fd_set inFd, outFd, excFd;
87 FD_ZERO(&inFd);
88 FD_ZERO(&outFd);
89 FD_ZERO(&excFd);
90
91 int maxFd = -1; // Not used on windows
92 SourceList::iterator it;
93 for (it=_sources.begin(); it!=_sources.end(); ++it) {
94 int fd = it->getSource()->getfd();
95 if (it->getMask() & ReadableEvent) FD_SET(fd, &inFd);
96 if (it->getMask() & WritableEvent) FD_SET(fd, &outFd);
97 if (it->getMask() & Exception) FD_SET(fd, &excFd);
98 if (it->getMask() && fd > maxFd) maxFd = fd;
99 }
100
101 // Check for events
102 int nEvents;
103 if (timeout < 0.0)
104 nEvents = select(maxFd+1, &inFd, &outFd, &excFd, NULL);
105 else
106 {
107 struct timeval tv;
108 tv.tv_sec = (int)floor(timeout);
109 tv.tv_usec = ((int)floor(1000000.0 * (timeout-floor(timeout)))) % 1000000;
110 nEvents = select(maxFd+1, &inFd, &outFd, &excFd, &tv);
111 }
112
113 if (nEvents < 0)
114 {
115 XmlRpcUtil::error("Error in XmlRpcDispatch::work: error in select (%d).", nEvents);
116 _inWork = false;
117 return;
118 }
119
120 // Process events
121 for (it=_sources.begin(); it != _sources.end(); )
122 {
123 SourceList::iterator thisIt = it++;
124 XmlRpcSource* src = thisIt->getSource();
125 int fd = src->getfd();
126 unsigned newMask = (unsigned) -1;
127 if (fd <= maxFd) {
128 // If you select on multiple event types this could be ambiguous
129 if (FD_ISSET(fd, &inFd))
130 newMask &= src->handleEvent(ReadableEvent);
131 if (FD_ISSET(fd, &outFd))
132 newMask &= src->handleEvent(WritableEvent);
133 if (FD_ISSET(fd, &excFd))
134 newMask &= src->handleEvent(Exception);
135
136 if ( ! newMask) {
137 _sources.erase(thisIt); // Stop monitoring this one
138 if ( ! src->getKeepOpen())
139 src->close();
140 } else if (newMask != (unsigned) -1) {
141 thisIt->getMask() = newMask;
142 }
143 }
144 }
145
146 // Check whether to clear all sources
147 if (_doClear)
148 {
149 SourceList closeList = _sources;
150 _sources.clear();
151 for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it) {
152 XmlRpcSource *src = it->getSource();
153 src->close();
154 }
155
156 _doClear = false;
157 }
158
159 // Check whether end time has passed
160 if (0 <= _endTime && getTime() > _endTime){
161 std::cout<< "XmlRpc : time out when connect to database " << std::endl;//yzhang debug
162 break;
163 }
164 }
165
166 _inWork = false;
167}
168
169
170// Exit from work routine. Presumably this will be called from
171// one of the source event handlers.
172void
174{
175 _endTime = 0.0; // Return from work asap
176}
177
178// Clear all sources from the monitored sources list
179void
181{
182 if (_inWork)
183 _doClear = true; // Finish reporting current events before clearing
184 else
185 {
186 SourceList closeList = _sources;
187 _sources.clear();
188 for (SourceList::iterator it=closeList.begin(); it!=closeList.end(); ++it)
189 it->getSource()->close();
190 }
191}
192
193
194double
196{
197#ifdef USE_FTIME
198 struct timeb tbuff;
199
200 ftime(&tbuff);
201 return ((double) tbuff.time + ((double)tbuff.millitm / 1000.0) +
202 ((double) tbuff.timezone * 60));
203#else
204 struct timeval tv;
205 struct timezone tz;
206
207 gettimeofday(&tv, &tz);
208 return (tv.tv_sec + tv.tv_usec / 1000000.0);
209#endif /* USE_FTIME */
210}
211
212
XmlRpcDispatch()
Constructor.
void removeSource(XmlRpcSource *source)
@ ReadableEvent
data available to read
@ WritableEvent
connected/data can be written without blocking
void work(double msTime)
void exit()
Exit from work routine.
void clear()
Clear all sources from the monitored sources list. Sources are closed.
void setSourceEvents(XmlRpcSource *source, unsigned eventMask)
Modify the types of events to watch for on this source.
std::list< MonitoredSource > SourceList
void addSource(XmlRpcSource *source, unsigned eventMask)
An RPC source represents a file descriptor to monitor.
Definition: XmlRpcSource.h:14
virtual void close()
Close the owned fd. If deleteOnClose was specified at construction, the object is deleted.
int getfd() const
Return the file descriptor being monitored.
Definition: XmlRpcSource.h:25
bool getKeepOpen() const
Return whether the file descriptor should be kept open if it is no longer monitored.
Definition: XmlRpcSource.h:30
virtual unsigned handleEvent(unsigned eventType)=0
Return true to continue monitoring this source.
static void error(const char *fmt,...)
Dump error messages somewhere.
Definition: XmlRpcUtil.cpp:85
Definition: XmlRpc.h:35