Commit 84483798 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

It seems FreeBSD does not unstack cancelation cleanups if we skip the pthread_cleanup_pop call

parent 41ee5bd0
......@@ -2221,7 +2221,7 @@ int fd_msg_update_length ( msg_or_avp * object )
/* 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 @@ int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_act
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 @@ int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_act
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 @@ int fd_msg_dispatch ( struct msg ** msg, struct session * session, enum disp_act
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;
}
......@@ -259,7 +259,6 @@ int main(int argc, char *argv[])
/* That's all for the tests yet */
free(sess_bkp);
fd_ext_fini();
PASSTEST();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment