ATLAS Offline Software
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 
10 #include <JiveXML/ONCRPCServer.h>
11 
12 #include <JiveXML/IServer.h>
13 #include <JiveXML/EventStream.h>
14 
15 #include <sstream>
16 #include <errno.h>
17 
18 namespace 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
JiveXML::SetNewEvent
void SetNewEvent(SVCXPRT *transp, const Event *event, IServer *const ServerSvc)
Implementation of ONCRPC_SETEVENT_PROC Set a new event for a certain streams.
Definition: ONCRPCServerProcs.cxx:189
JiveXML::ReturnStreams
void ReturnStreams(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of ONCRPC_GETSTREAMS_PROC Return the currently available event streams.
Definition: ONCRPCServerProcs.cxx:80
JiveXML::EventStreamID::EventNumber
unsigned long EventNumber() const
Definition: EventStream.h:41
JiveXML::IEventServer::GetStreamNames
virtual std::vector< std::string > GetStreamNames() const =0
get the names of all the streams
JiveXML::EventRequest_t::RunNumber
int64_t RunNumber
Definition: ONCRPCServer.h:60
JiveXML::EventStreamID::StreamNameCStr
const char * StreamNameCStr() const
Definition: EventStream.h:44
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
JiveXML::Streams_t::NStreams
unsigned int NStreams
Definition: ONCRPCServer.h:47
JiveXML::ReturnState
void ReturnState(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of ONCRPC_ATHENASTATUS_PROC Return the current athena status in XDR representation.
Definition: ONCRPCServerProcs.cxx:70
ONCRPCServer.h
JiveXML::EventRequest_t::EventNumber
int64_t EventNumber
Definition: ONCRPCServer.h:59
JiveXML::IEventServer::GetState
virtual int GetState() const =0
get the Status of the application
JiveXML::EventStreamID::isSameEvent
bool isSameEvent(const EventStreamID &id) const
Definition: EventStream.h:47
JiveXML::Streams_t::StreamNames
char ** StreamNames
Definition: ONCRPCServer.h:48
StateLessPT_NewConfig.StreamNames
StreamNames
Definition: StateLessPT_NewConfig.py:321
JiveXML::IEventServer::GetEventStreamID
virtual const EventStreamID GetEventStreamID(const std::string &streamName) const =0
get the current EventStreamID for a particular stream
JiveXML::xdr_streams
bool_t xdr_streams(XDR *xdrsp, Streams *streams)
De- and Encoding of Streams_t.
Definition: ONCRPCXDRProcs.cxx:19
JiveXML::EventRequest_t
Definition: ONCRPCServer.h:58
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
ONCRPCServerProcs.h
JiveXML::ReturnEvent
void ReturnEvent(SVCXPRT *transp, const EventRequest *eventReq, IServer *const ServerSvc)
Implementation of ONCRPC_GETEVENT_PROC Return an event from a certain streams.
Definition: ONCRPCServerProcs.cxx:112
JiveXML::xdr_event_req
bool_t xdr_event_req(XDR *xdrsp, EventRequest *eventReq)
De-/Encoding of EventRequest_t.
Definition: ONCRPCXDRProcs.cxx:32
JiveXML::xdr_event
bool_t xdr_event(XDR *xdrsp, Event *event)
De-/Encoding of Event_t.
Definition: ONCRPCXDRProcs.cxx:51
JiveXML::EventRequest_t::StreamName
const char * StreamName
Definition: ONCRPCServer.h:61
JiveXML::EventStreamID::isValid
bool isValid() const
Definition: EventStream.h:55
JiveXML::IMessage
Pure abstract interface to provide some athena-indepandant messaging Note that only MSG::Level enum i...
Definition: IMessage.h:16
TrigInDetValidation_Base.malloc
malloc
Definition: TrigInDetValidation_Base.py:127
ONCRPCXDRProcs.h
JiveXML::EventStreamID
For the client-server communication, each event is uniquely identified by the run number,...
Definition: EventStream.h:19
JiveXML::IEventReceiver::UpdateEventForStream
virtual StatusCode UpdateEventForStream(const EventStreamID &, const std::string &)=0
Put this event as new current event for stream given by name.
JiveXML
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
Definition: BadLArRetriever.cxx:22
JiveXML::Streams_t
Definition: ONCRPCServer.h:46
JiveXML::IMessage::Message
virtual void Message(const MSG::Level level, const std::string &msg) const =0
JiveXML::ReturnNull
void ReturnNull(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of NULLPROC Return nothing - server has just been pinged.
Definition: ONCRPCServerProcs.cxx:45
IServer.h
JiveXML::IServer
Pure abstract interface for all full server implementations.
Definition: IServer.h:22
JiveXML::ATLAS_THREAD_SAFE
pthread_key_t ServerSvcKey ATLAS_THREAD_SAFE
Definition: ONCRPCServerThreads.cxx:35
DEBUG
#define DEBUG
Definition: page_access.h:11
JiveXML::checkResult
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...
Definition: ONCRPCServerProcs.cxx:24
JiveXML::IEventServer::GetEvent
virtual const std::string GetEvent(const EventStreamID &evtStreamID) const =0
get the current event for a particular stream
JiveXML::Event_t
Definition: ONCRPCServer.h:66
checker_macros.h
Define macros for attributes used to control the static checker.
JiveXML::EventStreamID::RunNumber
unsigned int RunNumber() const
Definition: EventStream.h:42
EventStream.h
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7