comparison libfdproto/messages.c @ 690:a29e4201d511

It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call
author Sebastien Decugis <sdecugis@nict.go.jp>
date Thu, 20 Jan 2011 15:38:12 +0900
parents 933d098fc75d
children 289632905e19
comparison
equal deleted inserted replaced
689:933d098fc75d 690:a29e4201d511
2219 2219
2220 /***************************************************************************************************************/ 2220 /***************************************************************************************************************/
2221 /* Macro to check if further callbacks must be called */ 2221 /* Macro to check if further callbacks must be called */
2222 #define TEST_ACTION_STOP() \ 2222 #define TEST_ACTION_STOP() \
2223 if ((*msg == NULL) || (*action != DISP_ACT_CONT)) \ 2223 if ((*msg == NULL) || (*action != DISP_ACT_CONT)) \
2224 goto no_error; 2224 goto out;
2225 2225
2226 /* Call all dispatch callbacks for a given message */ 2226 /* Call all dispatch callbacks for a given message */
2227 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code) 2227 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code)
2228 { 2228 {
2229 struct dictionary * dict; 2229 struct dictionary * dict;
2230 struct dict_object * app; 2230 struct dict_object * app;
2231 struct dict_object * cmd; 2231 struct dict_object * cmd;
2232 struct avp * avp; 2232 struct avp * avp;
2233 struct fd_list * cb_list; 2233 struct fd_list * cb_list;
2234 int ret = 0; 2234 int ret = 0, r2;
2235 2235
2236 TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code); 2236 TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code);
2237 CHECK_PARAMS( msg && CHECK_MSG(*msg) && action); 2237 CHECK_PARAMS( msg && CHECK_MSG(*msg) && action);
2238 2238
2239 if (error_code) 2239 if (error_code)
2243 /* Take the dispatch lock */ 2243 /* Take the dispatch lock */
2244 CHECK_FCT( pthread_rwlock_rdlock(&fd_disp_lock) ); 2244 CHECK_FCT( pthread_rwlock_rdlock(&fd_disp_lock) );
2245 pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock ); 2245 pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock );
2246 2246
2247 /* First, call the DISP_HOW_ANY callbacks */ 2247 /* First, call the DISP_HOW_ANY callbacks */
2248 CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto error ); 2248 CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto out );
2249 2249
2250 TEST_ACTION_STOP(); 2250 TEST_ACTION_STOP();
2251 2251
2252 /* If we don't know the model at this point, we stop cause we cannot get the dictionary. It's invalid: an error should already have been trigged by ANY callbacks */ 2252 /* If we don't know the model at this point, we stop cause we cannot get the dictionary. It's invalid: an error should already have been trigged by ANY callbacks */
2253 CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto error; } ); 2253 CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto out; } );
2254 2254
2255 /* Now resolve message application */ 2255 /* Now resolve message application */
2256 CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto error ); 2256 CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto out );
2257 CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto error ); 2257 CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto out );
2258 2258
2259 if (app == NULL) { 2259 if (app == NULL) {
2260 if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) { 2260 if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) {
2261 if (error_code) 2261 if (error_code)
2262 *error_code = "DIAMETER_APPLICATION_UNSUPPORTED"; 2262 *error_code = "DIAMETER_APPLICATION_UNSUPPORTED";
2264 } else { 2264 } else {
2265 fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Internal error: Received this answer to a local query with an unsupported application %d", (*msg)->msg_public.msg_appl); 2265 fd_msg_log( FD_MSG_LOG_DROPPED, *msg, "Internal error: Received this answer to a local query with an unsupported application %d", (*msg)->msg_public.msg_appl);
2266 fd_msg_free(*msg); 2266 fd_msg_free(*msg);
2267 *msg = NULL; 2267 *msg = NULL;
2268 } 2268 }
2269 goto no_error; 2269 goto out;
2270 } 2270 }
2271 2271
2272 /* So start browsing the message */ 2272 /* So start browsing the message */
2273 CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto error ); 2273 CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto out );
2274 while (avp != NULL) { 2274 while (avp != NULL) {
2275 /* For unknown AVP, we don't have a callback registered, so just skip */ 2275 /* For unknown AVP, we don't have a callback registered, so just skip */
2276 if (avp->avp_model) { 2276 if (avp->avp_model) {
2277 struct dict_object * enumval = NULL; 2277 struct dict_object * enumval = NULL;
2278 2278
2279 /* Get the list of callback for this AVP */ 2279 /* Get the list of callback for this AVP */
2280 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto error ); 2280 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto out );
2281 2281
2282 /* We search enumerated values only in case of non-grouped AVP */ 2282 /* We search enumerated values only in case of non-grouped AVP */
2283 if ( avp->avp_public.avp_value ) { 2283 if ( avp->avp_public.avp_value ) {
2284 struct dict_object * type; 2284 struct dict_object * type;
2285 /* Check if the AVP has a constant value */ 2285 /* Check if the AVP has a constant value */
2286 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto error ); 2286 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto out );
2287 if (type) { 2287 if (type) {
2288 struct dict_enumval_request req; 2288 struct dict_enumval_request req;
2289 memset(&req, 0, sizeof(struct dict_enumval_request)); 2289 memset(&req, 0, sizeof(struct dict_enumval_request));
2290 req.type_obj = type; 2290 req.type_obj = type;
2291 memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) ); 2291 memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) );
2292 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto error ); 2292 CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto out );
2293 } 2293 }
2294 } 2294 }
2295 2295
2296 /* Call the callbacks */ 2296 /* Call the callbacks */
2297 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto error ); 2297 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto out );
2298 TEST_ACTION_STOP(); 2298 TEST_ACTION_STOP();
2299 } 2299 }
2300 /* Go to next AVP */ 2300 /* Go to next AVP */
2301 CHECK_FCT_DO( ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto error ); 2301 CHECK_FCT_DO( ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto out );
2302 } 2302 }
2303 2303
2304 /* Now call command and application callbacks */ 2304 /* Now call command and application callbacks */
2305 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto error ); 2305 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto out );
2306 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error ); 2306 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out );
2307 TEST_ACTION_STOP(); 2307 TEST_ACTION_STOP();
2308 2308
2309 if (app) { 2309 if (app) {
2310 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto error ); 2310 CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto out );
2311 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error ); 2311 CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out );
2312 TEST_ACTION_STOP(); 2312 TEST_ACTION_STOP();
2313 } 2313 }
2314 2314 out:
2315 ; /* some systems would complain without this */
2315 pthread_cleanup_pop(0); 2316 pthread_cleanup_pop(0);
2316 2317
2317 no_error: 2318 CHECK_POSIX_DO(r2 = pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ );
2318 CHECK_POSIX(pthread_rwlock_unlock(&fd_disp_lock) ); 2319 return ret ?: r2;
2319 return 0; 2320 }
2320 2321
2321 error: 2322
2322 CHECK_POSIX_DO(pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ );
2323 return ret;
2324 }
2325
2326
"Welcome to our mercurial repository"