1 /*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
18 #include "globus_i_service_engine.h"
19
20
21 typedef struct
22 {
23 globus_service_engine_t engine;
24 globus_service_engine_callback_func_t callback;
25 void * args;
26 globus_result_t result;
27 }
28 globus_l_service_engine_callback_handle_t;
29
30 static
31 void
32 globus_l_service_engine_session_started_callback(
33 globus_result_t result,
34 globus_service_engine_t engine,
35 globus_soap_message_handle_t session,
36 void * arg);
37
38 static
39 void
40 globus_l_service_engine_session_complete_callback(
41 globus_result_t result,
42 globus_service_engine_t engine,
43 globus_soap_message_handle_t session,
44 void * arg);
45
46 #endif /* GLOBUS_DONT_DOCUMENT_INTERNAL */
47 /**
48 * Start processing service requests
49 * @ingroup globus_service_engine
50 *
51 * Starts registering callbacks to process service requests on
52 * a service engine. The engine will continue to process new
53 * service requests until the globus_service_engine_register_stop()
54 * function is called.
55 *
56 * @param engine
57 * Service engine to start.
58 * @param stop_callback
59 * Callback to call after the engine has been stopped and all
60 * sessions have terminated.
61 * @param arg
62 * Application-specific callback to @a stop_callback
63 *
64 * @retval GLOBUS_SUCCESS
65 * Engine started successfully.
66 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAM
67 * The @a stop_callback parameter is NULL.
68 * @retval GLOBUS_SERVICE_ENGINE_ERROR_TYPE_ALREADY_STARTED
69 * The service engine has already been started.
70 * @retval GLOBUS_SERVICE_ENGINE_ERROR_TYPE_OUT_OF_MEMORY
71 * Insufficient memory to start the engine.
72 */
73 globus_result_t
74 globus_service_engine_register_start(
75 globus_service_engine_t engine,
76 globus_service_engine_callback_func_t stop_callback,
77 void * arg)
78 58 {
79 globus_l_service_engine_callback_handle_t * callback_handle;
80 58 globus_result_t result = GLOBUS_SUCCESS;
81 GlobusFuncName(globus_service_engine_register_start);
82 58 GlobusServiceEngineDebugEnter();
83
84 58 if (stop_callback == NULL)
85 {
86 0 result = GlobusSoapMessageErrorNullParam;
87
88 0 goto exit;
89 }
90 58 if(engine->stop_sessions)
91 {
92 0 result = GlobusServiceEngineErrorAlreadyStarted();
93 0 goto exit;
94 }
95
96 58 callback_handle = calloc(1,
97 sizeof(globus_l_service_engine_callback_handle_t));
98 58 if(!callback_handle)
99 {
100 0 result = GlobusServiceEngineErrorOutOfMemory;
101 0 goto exit;
102 }
103
104 58 callback_handle->engine = engine;
105 58 callback_handle->callback = stop_callback;
106 58 callback_handle->args = arg;
107
108 58 result = globus_service_engine_register_session(
109 engine,
110 globus_l_service_engine_session_started_callback,
111 callback_handle);
112
113 58 exit:
114
115 58 GlobusServiceEngineDebugExit();
116 58 return result;
117 }
118 /* globus_service_engine_register_start() */
119
120 #ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
121 static
122 void
123 globus_l_service_engine_session_started_callback(
124 globus_result_t result,
125 globus_service_engine_t engine,
126 globus_soap_message_handle_t session,
127 void * arg)
128 120 {
129 120 globus_result_t fault_result = GLOBUS_SUCCESS;
130 globus_l_service_engine_callback_handle_t *
131 callback_handle;
132 GlobusFuncName(globus_l_service_engine_session_started_callback);
133 120 GlobusServiceEngineDebugEnter();
134
135 120 callback_handle = arg;
136
137 120 GlobusServiceEngineLock(engine);
138
139 120 if(result != GLOBUS_SUCCESS)
140 {
141 40 result = GlobusServiceEngineErrorSessionStartFailed(result);
142 40 goto error_exit;
143 }
144
145 80 if(callback_handle->result != GLOBUS_SUCCESS)
146 {
147 0 fault_result = callback_handle->result;
148 }
149
150 80 engine->session_count++;
151 80 if(!engine->stop_sessions)
152 {
153 80 result = globus_service_engine_register_session(
154 engine,
155 globus_l_service_engine_session_started_callback,
156 callback_handle);
157 80 if(result != GLOBUS_SUCCESS)
158 {
159 0 engine->session_count--;
160
161 /* no more sessions started */
162 0 goto error_exit;
163 }
164 }
165
166 80 GlobusServiceEngineUnlock(engine);
167
168 80 result = globus_service_engine_register_process(
169 engine,
170 session,
171 fault_result,
172 globus_l_service_engine_session_complete_callback,
173 arg);
174
175 80 if (result != GLOBUS_SUCCESS)
176 {
177 0 GlobusServiceEngineLock(engine);
178 0 engine->session_count--;
179
180 0 goto error_exit;
181 }
182
183 80 goto exit;
184
185 40 error_exit:
186
187 40 if(result != GLOBUS_SUCCESS)
188 {
189 40 char * endpoint = NULL;
190 40 char * action = NULL;
191
192 40 if(session)
193 {
194 0 endpoint = globus_soap_message_handle_get_attr(
195 session,
196 GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY);
197
198 0 action = globus_soap_message_handle_get_attr(
199 session,
200 GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY);
201 }
202
203 40 GlobusServiceEngineDebugPrintError(result, endpoint, action);
204 }
205
206 40 if (globus_xio_error_is_canceled(result))
207 {
208 40 result = GLOBUS_SUCCESS;
209 }
210
211 40 if(engine->session_count <= 0)
212 {
213 40 GlobusServiceEngineUnlock(engine);
214 40 callback_handle->callback(result,
215 engine,
216 callback_handle->args);
217 40 free(callback_handle);
218 }
219 else
220 {
221 0 GlobusServiceEngineUnlock(engine);
222 }
223
224 120 exit:
225
226 120 GlobusServiceEngineDebugExit();
227 120 }
228 /* globus_l_service_engine_session_started_callback() */
229
230 static
231 void
232 globus_l_service_engine_session_complete_callback(
233 globus_result_t result,
234 globus_service_engine_t engine,
235 globus_soap_message_handle_t session,
236 void * arg)
237 68 {
238 globus_l_service_engine_callback_handle_t * callback_handle;
239 GlobusFuncName(globus_l_service_engine_session_complete_callback);
240 68 GlobusServiceEngineDebugEnter();
241
242 68 callback_handle = arg;
243
244 68 if(result != GLOBUS_SUCCESS)
245 {
246 0 char * endpoint = NULL;
247 0 char * action = NULL;
248
249 0 if(session)
250 {
251 0 endpoint = globus_soap_message_handle_get_attr(
252 session,
253 GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY);
254
255 0 action = globus_soap_message_handle_get_attr(
256 session,
257 GLOBUS_SOAP_MESSAGE_SOAP_ACTION_KEY);
258 }
259
260 0 GlobusServiceEngineDebugPrintError(result, endpoint, action);
261 }
262
263 68 GlobusServiceEngineLock(engine);
264 68 engine->session_count--;
265 68 if(engine->stop_sessions && engine->session_count <= 0)
266 {
267 0 GlobusServiceEngineUnlock(engine);
268
269 0 callback_handle->callback(
270 GLOBUS_SUCCESS, engine, callback_handle->args);
271
272 0 globus_free(callback_handle);
273 }
274 else
275 {
276 68 GlobusServiceEngineUnlock(engine);
277 }
278
279 68 globus_soap_message_handle_destroy(session);
280
281 68 GlobusServiceEngineDebugExit();
282 68 }
283 /* globus_l_service_engine_session_complete_callback() */
284