diff 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
line wrap: on
line diff
--- a/libfdproto/messages.c	Thu Jan 20 14:24:13 2011 +0900
+++ b/libfdproto/messages.c	Thu Jan 20 15:38:12 2011 +0900
@@ -2221,7 +2221,7 @@
 /* Macro to check if further callbacks must be called */
 #define TEST_ACTION_STOP()					\
 	if ((*msg == NULL) || (*action != DISP_ACT_CONT))	\
-		goto no_error;
+		goto out;
 
 /* Call all dispatch callbacks for a given message */
 int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_action *action, const char ** error_code)
@@ -2231,7 +2231,7 @@
 	struct dict_object * cmd;
 	struct avp * avp;
 	struct fd_list * cb_list;
-	int ret = 0;
+	int ret = 0, r2;
 	
 	TRACE_ENTRY("%p %p %p %p", msg, session, action, error_code);
 	CHECK_PARAMS( msg && CHECK_MSG(*msg) && action);
@@ -2245,16 +2245,16 @@
 	pthread_cleanup_push( fd_cleanup_rwlock, &fd_disp_lock );
 	
 	/* First, call the DISP_HOW_ANY callbacks */
-	CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto error );
+	CHECK_FCT_DO( ret = fd_disp_call_cb_int( NULL, msg, NULL, session, action, NULL, NULL, NULL, NULL ), goto out );
 
 	TEST_ACTION_STOP();
 	
 	/* 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 */
-	CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto error; } );
+	CHECK_PARAMS_DO(cmd = (*msg)->msg_model, { ret = EINVAL; goto out; } );
 	
 	/* Now resolve message application */
-	CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto error );
-	CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto error );
+	CHECK_FCT_DO( ret = fd_dict_getdict( cmd, &dict ), goto out );
+	CHECK_FCT_DO( ret = fd_dict_search( dict, DICT_APPLICATION, APPLICATION_BY_ID, &(*msg)->msg_public.msg_appl, &app, 0 ), goto out );
 	
 	if (app == NULL) {
 		if ((*msg)->msg_public.msg_flags & CMD_FLAG_REQUEST) {
@@ -2266,61 +2266,57 @@
 			fd_msg_free(*msg);
 			*msg = NULL;
 		}
-		goto no_error;
+		goto out;
 	}
 	
 	/* So start browsing the message */
-	CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto error );
+	CHECK_FCT_DO( ret = fd_msg_browse( *msg, MSG_BRW_FIRST_CHILD, &avp, NULL ), goto out );
 	while (avp != NULL) {
 		/* For unknown AVP, we don't have a callback registered, so just skip */
 		if (avp->avp_model) {
 			struct dict_object * enumval = NULL;
 			
 			/* Get the list of callback for this AVP */
-			CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto error );
+			CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_AVP, avp->avp_model, &cb_list), goto out );
 			
 			/* We search enumerated values only in case of non-grouped AVP */
 			if ( avp->avp_public.avp_value ) {
 				struct dict_object * type;
 				/* Check if the AVP has a constant value */
-				CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto error );
+				CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &type, 0), goto out );
 				if (type) {
 					struct dict_enumval_request req;
 					memset(&req, 0, sizeof(struct dict_enumval_request));
 					req.type_obj = type;
 					memcpy( &req.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value) );
-					CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto error );
+					CHECK_FCT_DO( ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &req, &enumval, 0), goto out );
 				}
 			}
 			
 			/* Call the callbacks */
-			CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto error );
+			CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, avp, session, action, app, cmd, avp->avp_model, enumval ), goto out );
 			TEST_ACTION_STOP();
 		}
 		/* Go to next AVP */
-		CHECK_FCT_DO(  ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto error );
+		CHECK_FCT_DO(  ret = fd_msg_browse( avp, MSG_BRW_WALK, &avp, NULL ), goto out );
 	}
 		
 	/* Now call command and application callbacks */
-	CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto error );
-	CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error );
+	CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_COMMAND, cmd, &cb_list), goto out );
+	CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out );
 	TEST_ACTION_STOP();
 	
 	if (app) {
-		CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto error );
-		CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto error );
+		CHECK_FCT_DO( ret = fd_dict_disp_cb(DICT_APPLICATION, app, &cb_list), goto out );
+		CHECK_FCT_DO( ret = fd_disp_call_cb_int( cb_list, msg, NULL, session, action, app, cmd, NULL, NULL ), goto out );
 		TEST_ACTION_STOP();
 	}
-	
+out:
+	; /* some systems would complain without this */	
 	pthread_cleanup_pop(0);
 	
-no_error:
-	CHECK_POSIX(pthread_rwlock_unlock(&fd_disp_lock) );
-	return 0;
-	
-error:
-	CHECK_POSIX_DO(pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ );
-	return ret;
+	CHECK_POSIX_DO(r2 = pthread_rwlock_unlock(&fd_disp_lock), /* ignore */ );
+	return ret ?: r2;
 }
 
 
"Welcome to our mercurial repository"