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 (!svc_sendreply(transp, (xdrproc_t)xdr_void, 0))
52  //check global errno variable on result
53  checkResult(errno,"dispatch thread sending reply to NULLPROC call",ServerSvc);
54  }
55 #if __GNUC__ >= 8
56 # pragma GCC diagnostic pop
57 #endif
58 
63  void ReturnState( SVCXPRT* transp, IServer* const ServerSvc ){
64  int state = ServerSvc->GetState();
65  if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (caddr_t)&state))
66  //check global errno variable on result
67  checkResult(errno,"dispatch thread sending reply to GETSTATUS call",ServerSvc);
68  }
69 
73  void ReturnStreams( SVCXPRT* transp, IServer* const ServerSvc ){
74 
75  // First of all get the list of names
76  std::vector<std::string> StreamNames = ServerSvc->GetStreamNames();
77 
78  // Create a new XDR data structure to fill in the streams
79  Streams XDRStreams;
80 
81  // Fill in number of streams
82  XDRStreams.NStreams = StreamNames.size();
83 
84  //Create a new array with the stream names
85  XDRStreams.StreamNames = (char**) malloc(StreamNames.size()*sizeof(char*));
86 
87  //Fill in all the names themselves
88  for ( unsigned int iName = 0; iName < StreamNames.size(); ++iName)
89  XDRStreams.StreamNames[iName] = strdup(StreamNames[iName].c_str());
90 
91  //return that object
92  if (!svc_sendreply(transp, (xdrproc_t)xdr_streams, (caddr_t)&XDRStreams))
93  checkResult(errno,"dispatch thread sending reply to GETSTREAMS call",ServerSvc);
94 
95  //Afterwards free the object
96  xdr_free((xdrproc_t)xdr_streams,(caddr_t)&XDRStreams);
97  }
98 
105  void ReturnEvent( SVCXPRT* transp, const EventRequest* eventReq, IServer* const ServerSvc ){
106 
107  //Check if there was an event request
108  std::ostringstream msg;
109  if (! eventReq ) {
110  msg << "Request to return event with void event request structure";
111  ServerSvc->Message(MSG::ERROR,msg.str());
112  svcerr_systemerr(transp);
113  return ;
114  }
115 
116  //Be a bit verbose
117  msg << "Request for stream " << eventReq->StreamName
118  << " with existing event " << eventReq->EventNumber
119  << " from run " << eventReq->RunNumber;
120  //Send message an clear stream
121  ServerSvc->Message(MSG::DEBUG,msg.str()); msg.str("");
122 
123  //Next get the current eventStreamID from that stream
124  EventStreamID currEvtStreamID = ServerSvc->GetEventStreamID(eventReq->StreamName);
125 
126  //Also get an event stream ID for the requested event
127  EventStreamID reqEvtStreamID(eventReq->EventNumber,eventReq->RunNumber,eventReq->StreamName);
128 
129  //We got all the data from the request, so delete it
130  caddr_t nc_eventReq ATLAS_THREAD_SAFE = (caddr_t)eventReq;
131  xdr_free((xdrproc_t)xdr_event_req,nc_eventReq);
132 
133  //Prepare response structure
134  Event event;
135  event.isAvailable = false ;
136  event.isIdentical = false ;
137  event.isCompressed = false ;
138  event.EventNumber = currEvtStreamID.EventNumber();
139  event.RunNumber = currEvtStreamID.RunNumber();
140  event.StreamName = currEvtStreamID.StreamNameCStr();
141  event.NBytes = 0; event.EventData = NULL ;
142 
143  //Check if such a stream was currently found
144  if (!currEvtStreamID.isValid()) {
145  // Sending reply with "no such stream" - i.e unmodified event structure
146  msg << "Sending response NO SUCH STREAM "; ServerSvc->Message(MSG::DEBUG,msg.str());
147  if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
148  checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
149  return ;
150  } else
151  //We have an event in that stream
152  event.isAvailable = true ;
153 
154  //Check if this is the same event the user already has
155  if ( currEvtStreamID.isSameEvent(reqEvtStreamID) ){
156  // Set the same event flag
157  event.isIdentical = true ;
158  // Sending reply with "same event"
159  msg << "Sending response SAME EVENT "; ServerSvc->Message(MSG::DEBUG,msg.str());
160  if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
161  checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
162  return ;
163  }
164 
165  //Otherwise just get the event itself
166  std::string evt = ServerSvc->GetEvent( currEvtStreamID );
167  event.EventData = evt.c_str();
168  event.NBytes = strlen(evt.c_str())+1; //including null-termination character
169  //Send reply with an actual event
170  msg << "Sending response NEW EVENT (" << event.EventNumber << ","<< event.RunNumber << ")" ;
171  ServerSvc->Message(MSG::DEBUG,msg.str());
172  if (!svc_sendreply(transp, (xdrproc_t)xdr_event, (caddr_t)&event))
173  checkResult(errno,"dispatch thread sending reply to GETEVENT call",ServerSvc);
174 
175  //No need to use xdr_free to free the returned event object since we did
176  //not allocate resources for it (just point the pointers to the proper place).
177  }
178 
182  void SetNewEvent( SVCXPRT* transp, const Event* event, IServer* const ServerSvc ){
183 
184  //Check if there was a valid event request
185  //NOTE: Event number can be 0, run number can not
186  std::ostringstream msg;
187  if ( (!event) || (event->EventNumber<0) || (!event->RunNumber) || (!event->StreamName) ) {
188  msg << "Request to set new event with void or invalid event structure";
189  ServerSvc->Message(MSG::ERROR,msg.str());
190  svcerr_systemerr(transp);
191  return ;
192  }
193 
194  //Be a bit verbose
195  msg << "Request to set new event " << event->EventNumber
196  << " from run " << event->RunNumber
197  << " for stream " << event->StreamName;
198  //Send message an clear stream
199  ServerSvc->Message(MSG::DEBUG,msg.str()); msg.str("");
200 
201  //The success flag returned to the client
202  //Need to use bool_t (4bytes) instead of bool (1byte)!
203  bool_t isSuccess=false;
204 
205  //Create a new EventStreamID from the data we have got
206  EventStreamID newEvtStreamID(event->EventNumber,event->RunNumber,event->StreamName);
207 
208  //Make sure this ID is valid
209  if (! newEvtStreamID.isValid()) {
210  msg << "Request to set new event with invalid stream name or event/run number";
211  ServerSvc->Message(MSG::ERROR,msg.str());
212  if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
213  checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
214  return ;
215  }
216 
217  //And make sure there is data
218  if ((! event->EventData ) || (strlen(event->EventData) == 0)){
219  msg << "Request to set new event with invalid event data";
220  ServerSvc->Message(MSG::ERROR,msg.str());
221  if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
222  checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
223  return ;
224  }
225 
226  //Also make sure it has the proper length
227  if ( strlen(event->EventData) != event->NBytes -1 ){
228  msg << "Event string length does not match claimed number of bytes (null-termination problem?)";
229  ServerSvc->Message(MSG::ERROR,msg.str());
230  if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
231  checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
232  return ;
233  }
234  //Get the event data
235  std::string EvtData(event->EventData);
236 
237  //Now set the event at the server
238  if (ServerSvc->UpdateEventForStream( newEvtStreamID, EvtData).isSuccess())
239  //and set the success flag
240  isSuccess = true;
241 
242  //Show the result
243  msg << "Sending response for set new event: ";
244  if (isSuccess) msg << " SUCCESS!"; else msg << " FAILED!";
245  ServerSvc->Message(MSG::DEBUG,msg.str());
246  //Send the reply
247  if (!svc_sendreply(transp, (xdrproc_t)xdr_bool, (caddr_t)&isSuccess))
248  checkResult(errno,"dispatch thread sending reply to SETEVENT call",ServerSvc);
249 
250  //Afterwards free the object
251  caddr_t nc_event ATLAS_THREAD_SAFE = (caddr_t)event;
252  xdr_free((xdrproc_t)xdr_event,nc_event);
253  }
254 
255 } //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:182
JiveXML::ReturnStreams
void ReturnStreams(SVCXPRT *transp, IServer *const ServerSvc)
Implementation of ONCRPC_GETSTREAMS_PROC Return the currently available event streams.
Definition: ONCRPCServerProcs.cxx:73
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:63
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:315
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:105
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:132
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