ATLAS Offline Software
Loading...
Searching...
No Matches
ONCRPCServerProcs.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7
11
12#include <JiveXML/IServer.h>
13#include <JiveXML/EventStream.h>
14
15#include <sstream>
16#include <errno.h>
17
18namespace JiveXML {
19
24 bool checkResult( const int RetVal, const std::string& Module, IMessage* const ServerSvc){
25
26 //Immediately return on no error
27 if (RetVal == 0) return true ;
28
29 //If there was an error, assemble the message
30 std::ostringstream msg;
31 char errbuf[256];
32 msg << "Error in " << Module << ": " << strerror_r(RetVal, errbuf, sizeof(errbuf));
33
34 //Output the message via the ServerSvc
35 ServerSvc->Message(MSG::ERROR,msg.str());
36
37 //In case of error return false
38 return false ;
39 }
40
45 void ReturnNull( SVCXPRT* transp, IServer* const ServerSvc ){
46// xdr_void is defined inconsistently in xdr.h and gets a warning from gcc8.
47#if __GNUC__ >= 8
48# pragma GCC diagnostic push
49# pragma GCC diagnostic ignored "-Wcast-function-type"
50#endif
51#if defined(__clang__) && __clang_major__ >= 19
52# pragma clang diagnostic push
53# pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
54#endif
55 if (!svc_sendreply(transp, (xdrproc_t)xdr_void, 0))
56 //check global errno variable on result
57 checkResult(errno,"dispatch thread sending reply to NULLPROC call",ServerSvc);
58 }
59#if defined(__clang__) && __clang_major__ >= 19
60# pragma clang diagnostic pop
61#endif
62#if __GNUC__ >= 8
63# pragma GCC diagnostic pop
64#endif
65
70 void ReturnState( SVCXPRT* transp, IServer* const ServerSvc ){
71 int state = ServerSvc->GetState();
72 if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (caddr_t)&state))
73 //check global errno variable on result
74 checkResult(errno,"dispatch thread sending reply to GETSTATUS call",ServerSvc);
75 }
76
80 void ReturnStreams( SVCXPRT* transp, IServer* const ServerSvc ){
81
82 // First of all get the list of names
83 std::vector<std::string> StreamNames = ServerSvc->GetStreamNames();
84
85 // Create a new XDR data structure to fill in the streams
86 Streams XDRStreams;
87
88 // Fill in number of streams
89 XDRStreams.NStreams = StreamNames.size();
90
91 //Create a new array with the stream names
92 XDRStreams.StreamNames = (char**) malloc(StreamNames.size()*sizeof(char*));
93
94 //Fill in all the names themselves
95 for ( unsigned int iName = 0; iName < StreamNames.size(); ++iName)
96 XDRStreams.StreamNames[iName] = strdup(StreamNames[iName].c_str());
97
98 //return that object
99 if (!svc_sendreply(transp, (xdrproc_t)xdr_streams, (caddr_t)&XDRStreams))
100 checkResult(errno,"dispatch thread sending reply to GETSTREAMS call",ServerSvc);
101
102 //Afterwards free the object
103 xdr_free((xdrproc_t)xdr_streams,(caddr_t)&XDRStreams);
104 }
105
112 void ReturnEvent( SVCXPRT* transp, const EventRequest* eventReq, IServer* const ServerSvc ){
113
114 //Check if there was an event request
115 std::ostringstream msg;
116 if (! eventReq ) {
117 msg << "Request to return event with void event request structure";
118 ServerSvc->Message(MSG::ERROR,msg.str());
119 svcerr_systemerr(transp);
120 return ;
121 }
122
123 //Be a bit verbose
124 msg << "Request for stream " << eventReq->StreamName
125 << " with existing event " << eventReq->EventNumber
126 << " from run " << eventReq->RunNumber;
127 //Send message an clear stream
128 ServerSvc->Message(MSG::DEBUG,msg.str()); msg.str("");
129
130 //Next get the current eventStreamID from that stream
131 EventStreamID currEvtStreamID = ServerSvc->GetEventStreamID(eventReq->StreamName);
132
133 //Also get an event stream ID for the requested event
134 EventStreamID reqEvtStreamID(eventReq->EventNumber,eventReq->RunNumber,eventReq->StreamName);
135
136 //We got all the data from the request, so delete it
137 caddr_t nc_eventReq ATLAS_THREAD_SAFE = (caddr_t)eventReq;
138 xdr_free((xdrproc_t)xdr_event_req,nc_eventReq);
139
140 //Prepare response structure
141 Event event;
142 event.isAvailable = false ;
143 event.isIdentical = false ;
144 event.isCompressed = false ;
145 event.EventNumber = currEvtStreamID.EventNumber();
146 event.RunNumber = currEvtStreamID.RunNumber();
147 event.StreamName = currEvtStreamID.StreamNameCStr();
148 event.NBytes = 0; event.EventData = NULL ;
149
150 //Check if such a stream was currently found
151 if (!currEvtStreamID.isValid()) {
152 // Sending reply with "no such stream" - i.e unmodified event structure
153 msg << "Sending response NO SUCH STREAM "; ServerSvc->Message(MSG::DEBUG,msg.str());
154 if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
155 checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
156 return ;
157 } else
158 //We have an event in that stream
159 event.isAvailable = true ;
160
161 //Check if this is the same event the user already has
162 if ( currEvtStreamID.isSameEvent(reqEvtStreamID) ){
163 // Set the same event flag
164 event.isIdentical = true ;
165 // Sending reply with "same event"
166 msg << "Sending response SAME EVENT "; ServerSvc->Message(MSG::DEBUG,msg.str());
167 if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
168 checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
169 return ;
170 }
171
172 //Otherwise just get the event itself
173 std::string evt = ServerSvc->GetEvent( currEvtStreamID );
174 event.EventData = evt.c_str();
175 event.NBytes = strlen(evt.c_str())+1; //including null-termination character
176 //Send reply with an actual event
177 msg << "Sending response NEW EVENT (" << event.EventNumber << ","<< event.RunNumber << ")" ;
178 ServerSvc->Message(MSG::DEBUG,msg.str());
179 if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
180 checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
181
182 //No need to use xdr_free to free the returned event object since we did
183 //not allocate resources for it (just point the pointers to the proper place).
184 }
185
189 void SetNewEvent( SVCXPRT* transp, const Event* event, IServer* const ServerSvc ){
190
191 //Check if there was a valid event request
192 //NOTE: Event number can be 0, run number can not
193 std::ostringstream msg;
194 if ( (!event) || (event->EventNumber<0) || (!event->RunNumber) || (!event->StreamName) ) {
195 msg << "Request to set new event with void or invalid event structure";
196 ServerSvc->Message(MSG::ERROR,msg.str());
197 svcerr_systemerr(transp);
198 return ;
199 }
200
201 //Be a bit verbose
202 msg << "Request to set new event " << event->EventNumber
203 << " from run " << event->RunNumber
204 << " for stream " << event->StreamName;
205 //Send message an clear stream
206 ServerSvc->Message(MSG::DEBUG,msg.str()); msg.str("");
207
208 //The success flag returned to the client
209 //Need to use bool_t (4bytes) instead of bool (1byte)!
210 bool_t isSuccess=false;
211
212 //Create a new EventStreamID from the data we have got
213 EventStreamID newEvtStreamID(event->EventNumber,event->RunNumber,event->StreamName);
214
215 //Make sure this ID is valid
216 if (! newEvtStreamID.isValid()) {
217 msg << "Request to set new event with invalid stream name or event/run number";
218 ServerSvc->Message(MSG::ERROR,msg.str());
219 if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
220 checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
221 return ;
222 }
223
224 //And make sure there is data
225 if ((! event->EventData ) || (strlen(event->EventData) == 0)){
226 msg << "Request to set new event with invalid event data";
227 ServerSvc->Message(MSG::ERROR,msg.str());
228 if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
229 checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
230 return ;
231 }
232
233 //Also make sure it has the proper length
234 if ( strlen(event->EventData) != event->NBytes -1 ){
235 msg << "Event string length does not match claimed number of bytes (null-termination problem?)";
236 ServerSvc->Message(MSG::ERROR,msg.str());
237 if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
238 checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
239 return ;
240 }
241 //Get the event data
242 std::string EvtData(event->EventData);
243
244 //Now set the event at the server
245 if (ServerSvc->UpdateEventForStream( newEvtStreamID, EvtData).isSuccess())
246 //and set the success flag
247 isSuccess = true;
248
249 //Show the result
250 msg << "Sending response for set new event: ";
251 if (isSuccess) msg << " SUCCESS!"; else msg << " FAILED!";
252 ServerSvc->Message(MSG::DEBUG,msg.str());
253 //Send the reply
254 if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
255 checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
256
257 //Afterwards free the object
258 caddr_t nc_event ATLAS_THREAD_SAFE = (caddr_t)event;
259 xdr_free((xdrproc_t)xdr_event,nc_event);
260 }
261
262} //namespace
Define macros for attributes used to control the static checker.
For the client-server communication, each event is uniquely identified by the run number,...
Definition EventStream.h:19
bool isSameEvent(const EventStreamID &id) const
Definition EventStream.h:47
unsigned int RunNumber() const
Definition EventStream.h:42
unsigned long EventNumber() const
Definition EventStream.h:41
const char * StreamNameCStr() const
Definition EventStream.h:44
virtual StatusCode UpdateEventForStream(const EventStreamID &, const std::string &)=0
Put this event as new current event for stream given by name.
virtual const EventStreamID GetEventStreamID(const std::string &streamName) const =0
get the current EventStreamID for a particular stream
virtual std::vector< std::string > GetStreamNames() const =0
get the names of all the streams
virtual int GetState() const =0
get the Status of the application
virtual const std::string GetEvent(const EventStreamID &evtStreamID) const =0
get the current event for a particular stream
Pure abstract interface to provide some athena-indepandant messaging Note that only MSG::Level enum i...
Definition IMessage.h:16
virtual void Message(const MSG::Level level, const std::string &msg) const =0
Pure abstract interface for all full server implementations.
Definition IServer.h:22
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
void ReturnState(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of ONCRPC_ATHENASTATUS_PROC Return the current athena status in XDR representation.
bool_t xdr_event_req(XDR *xdrsp, EventRequest *eventReq)
De-/Encoding of EventRequest_t.
void ReturnEvent(SVCXPRT *transp, const EventRequest *eventReq, IServer *const ServerSvc)
Implementation of ONCRPC_GETEVENT_PROC Return an event from a certain streams.
void ReturnStreams(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of ONCRPC_GETSTREAMS_PROC Return the currently available event streams.
bool checkResult(const int RetVal, const std::string &Module, IMessage *const ServerSvc)
Simple result checking routine, that will output an errorMsg throught the ServerSvc if there was an e...
struct EventRequest_t EventRequest
Data structures for GetEvent functions.
void SetNewEvent(SVCXPRT *transp, const Event *event, IServer *const ServerSvc)
Implementation of ONCRPC_SETEVENT_PROC Set a new event for a certain streams.
void ReturnNull(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of NULLPROC Return nothing - server has just been pinged.
bool_t xdr_streams(XDR *xdrsp, Streams *streams)
De- and Encoding of Streams_t.
struct Streams_t Streams
Data structures for GetStreams functions.
struct Event_t Event
pthread_key_t ServerSvcKey ATLAS_THREAD_SAFE
bool_t xdr_event(XDR *xdrsp, Event *event)
De-/Encoding of Event_t.
unsigned int NStreams
MsgStream & msg
Definition testRead.cxx:32