ATLAS Offline Software
Loading...
Searching...
No Matches
ExternalONCRPCServerSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include <rpc/rpc.h>
9
10namespace JiveXML {
11
12
16 ExternalONCRPCServerSvc::ExternalONCRPCServerSvc( const std::string& name, ISvcLocator* sl) :
17 base_class ( name, sl ),
18 m_client(NULL)
19 {
20 //declare properties
21 declareProperty("Hostname",m_hostName="localhost","The name of the host the external server is running on [ default: \"localhost\" ]");
22 declareProperty("Timeout",m_timeOut=10,"Timeout when calling the server in seconds [ default: 10 ]");
23 }
24
31
37 ATH_MSG_VERBOSE( "Initialize()" );
38
39 //Initialize Service base
40 if (Service::initialize().isFailure()) return StatusCode::FAILURE;
41
42 //Initialize message stream level
43 msg().setLevel(outputLevel());
44 ATH_MSG_VERBOSE( "Output level is set to " << (int)msg().level() );
45
49 GetClient().ignore();
50
51 return StatusCode::SUCCESS;
52 }
53
60
61 ATH_MSG_VERBOSE( "GetClient()" );
62
63 //Try to create client if not there yet
64#ifndef __APPLE__
65 if (!m_client) m_client = clnt_create(m_hostName.c_str(), ONCRPCSERVERPROG,ONCRPCSERVERVERS, "tcp");
66#else
67 char proto[] = "tcp";
68 if (!m_client) m_client = clnt_create((char*)m_hostName.c_str(), ONCRPCSERVERPROG,ONCRPCSERVERVERS, proto);
69#endif
70 //Fail if we still don't have a client
71 if (!m_client){
72 ATH_MSG_WARNING( "Unable to create client for server on host " << m_hostName << " using TCP/IP " );
73 return StatusCode::FAILURE;
74 }
75
76// xdr_void is defined inconsistently in xdr.h and gets a warning from gcc8.
77#if __GNUC__ >= 8
78# pragma GCC diagnostic push
79# pragma GCC diagnostic ignored "-Wcast-function-type"
80#endif
81#if defined(__clang__) && __clang_major__ >= 19
82# pragma clang diagnostic push
83# pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
84#endif
85 //Now try pinging the server
86 clnt_stat ret = clnt_call(m_client, NULLPROC, (xdrproc_t)xdr_void, NULL,
87 (xdrproc_t)xdr_void, NULL, GetTimeout());
88#if defined(__clang__) && __clang_major__ >= 19
89# pragma clang diagnostic pop
90#endif
91#if __GNUC__ >= 8
92# pragma GCC diagnostic pop
93#endif
94
95 //And check for the result
96 if (ret != RPC_SUCCESS){
97 ATH_MSG_WARNING( "Failed calling the server on host " << m_hostName << " : " << clnt_sperrno(ret) );
98 //Also destroy the client in this case - otherwise we might be stranded
99 //with an invalid client object
100 ReleaseClient().ignore();
101 //and return failure
102 return StatusCode::FAILURE;
103 }
104
105 //Be verbose on success
106 ATH_MSG_VERBOSE( "Successfully connected to server on host " << m_hostName );
107
108 return StatusCode::SUCCESS;
109 }
110
115 //Declare return value
116 struct timeval timeout = { 0, 0 };
117 //Catch for negatives
118 if (m_timeOut < 0) return timeout;
119 //Get seconds as integer part
120 timeout.tv_sec = static_cast<long>(m_timeOut);
121 //Get microseconds as fractional part
122 timeout.tv_usec = static_cast<long>((m_timeOut - timeout.tv_sec)*1e6);
123 //Finally return it
124 return timeout;
125 }
126
131 //Destroy the client
132 if (m_client) clnt_destroy(m_client);
133 //And set pointer to NULL
134 m_client=NULL;
135 //For now always return success
136 return StatusCode::SUCCESS;
137 }
138
144
145 ATH_MSG_VERBOSE( "Finalize()" );
146
150 ReleaseClient().ignore();
151
152 return StatusCode::SUCCESS;
153 }
154
159 StatusCode ExternalONCRPCServerSvc::UpdateEventForStream( const EventStreamID& evtStreamID, const std::string & eventStr) {
160
161 ATH_MSG_VERBOSE( "UpdateEventForStream()" );
162
163 //Check that the event stream id is valid
164 if (!evtStreamID.isValid()){
165 ATH_MSG_ERROR( "Invalid event stream identifier - cannot add event" );
166 return StatusCode::FAILURE;
167 }
168
169 //Now create an event C-struct that we can send to the server
170 //NOTE: the struct has to be properly initialized
171 Event event;
172 event.isAvailable = false ; event.isIdentical = false ; event.isCompressed = false ;
173 event.RunNumber = evtStreamID.RunNumber();
174 event.EventNumber=evtStreamID.EventNumber();
175 event.StreamName=strdup(evtStreamID.StreamName().c_str());
176 event.NBytes = strlen(eventStr.c_str())+1;
177 event.EventData = strdup(eventStr.c_str());
178
179 ATH_MSG_VERBOSE( "Created event structure for event " << event.EventNumber
180 << " from run " << event.RunNumber
181 << " to be put in stream " << event.StreamName
182 << " with " << event.NBytes << " bytes" );
183
184 //Try to get a client
185 if (GetClient().isFailure()) {
186 ATH_MSG_WARNING( "Failed obtaining a client for sever on host " << m_hostName );
187 ATH_MSG_WARNING( " while updating stream " << evtStreamID.StreamName()
188 << " with event " << evtStreamID.EventNumber()
189 << " from run " << evtStreamID.RunNumber() );
190 //delete char * strings malloc'ed by strdup
191 //are checkers enabled here?
192 auto *p1 = const_cast<char*>(event.StreamName);
193 auto *p2 = const_cast<char*>(event.EventData);
194 free(p1);
195 free(p2);
196 return StatusCode::FAILURE;
197 }
198
199 //Call the client to update the event
200 bool isSuccess = false;
201 clnt_stat ret = clnt_call(m_client, ONCRPC_SETEVENT_PROC, (xdrproc_t)xdr_event, (caddr_t)&event,
202 (xdrproc_t)xdr_bool,(caddr_t)&isSuccess, GetTimeout());
203
204 //And check for the result
205 if (ret != RPC_SUCCESS){
206 ATH_MSG_WARNING( "Failed calling the server on host " << m_hostName << " : " << clnt_sperrno(ret) );
207 ATH_MSG_WARNING( " while updating stream " << evtStreamID.StreamName()
208 << " with event " << evtStreamID.EventNumber()
209 << " from run " << evtStreamID.RunNumber() );
210 return StatusCode::FAILURE;
211 }
212
213 //Check if the server managed to update the event from return value
214 if (!isSuccess){
215 ATH_MSG_WARNING( "Server on host " << m_hostName << " returned failure " );
216 ATH_MSG_WARNING( " while updating stream " << evtStreamID.StreamName()
217 << " with event " << evtStreamID.EventNumber()
218 << " from run " << evtStreamID.RunNumber() );
219 return StatusCode::FAILURE;
220 }
221
222 //Be verbose on success
223 ATH_MSG_DEBUG( "Server on host " << m_hostName << " returned success " );
224 ATH_MSG_DEBUG( " while updating stream " << evtStreamID.StreamName()
225 << " with event " << evtStreamID.EventNumber()
226 << " from run " << evtStreamID.RunNumber() );
227
228 //Finally free the memory allocated for the event structure
229 xdr_free((xdrproc_t)xdr_event,(caddr_t)&event);
230
231 return StatusCode::SUCCESS;
232 }
233
234} //namespace
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define ONCRPCSERVERVERS
#define ONCRPC_SETEVENT_PROC
#define ONCRPCSERVERPROG
For the client-server communication, each event is uniquely identified by the run number,...
Definition EventStream.h:19
unsigned int RunNumber() const
Definition EventStream.h:42
unsigned long EventNumber() const
Definition EventStream.h:41
const std::string & StreamName() const
Definition EventStream.h:43
virtual StatusCode initialize() override
Gaudi default methods.
StatusCode ReleaseClient()
Destroy the private client handle.
StatusCode GetClient()
Obtain a client handle by.
virtual StatusCode finalize() override
Finalize - called once at the end.
virtual StatusCode UpdateEventForStream(const EventStreamID &evtStreamID, const std::string &event) override
Put this event as new current event for stream given by name.
struct timeval GetTimeout()
Convert timeout double in seconds to struct timeval.
ExternalONCRPCServerSvc(const std::string &name, ISvcLocator *sl)
Default constructor.
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
struct Event_t Event
bool_t xdr_event(XDR *xdrsp, Event *event)
De-/Encoding of Event_t.
MsgStream & msg
Definition testRead.cxx:32