|
25 | 25 | #include "rcl/lexer_lookahead.h" |
26 | 26 | #include "rcl/validate_topic_name.h" |
27 | 27 | #include "rcl_yaml_param_parser/parser.h" |
| 28 | +#include "rcl_yaml_param_parser/parser_thread_attr.h" |
28 | 29 | #include "rcl_yaml_param_parser/types.h" |
29 | 30 | #include "rcutils/allocator.h" |
30 | 31 | #include "rcutils/error_handling.h" |
@@ -286,6 +287,12 @@ rcl_parse_arguments( |
286 | 287 | goto fail; |
287 | 288 | } |
288 | 289 |
|
| 290 | + args_impl->thread_attrs = rcl_get_zero_initialized_thread_attrs(); |
| 291 | + ret = rcl_thread_attrs_init(&args_impl->thread_attrs, allocator); |
| 292 | + if (RCL_RET_OK != ret) { |
| 293 | + goto fail; |
| 294 | + } |
| 295 | + |
289 | 296 | args_impl->parameter_overrides = rcl_yaml_node_struct_init(allocator); |
290 | 297 | if (NULL == args_impl->parameter_overrides) { |
291 | 298 | ret = RCL_RET_BAD_ALLOC; |
@@ -559,6 +566,73 @@ rcl_parse_arguments( |
559 | 566 | RCL_DISABLE_FLAG_PREFIX, RCL_LOG_EXT_LIB_FLAG_SUFFIX, rcl_get_error_string().str); |
560 | 567 | rcl_reset_error(); |
561 | 568 |
|
| 569 | + // Attempt to parse argument as thread attribute flag |
| 570 | + if (strcmp(RCL_THREAD_ATTRS_VALUE_FLAG, argv[i]) == 0) { |
| 571 | + if (i + 1 < argc) { |
| 572 | + if (args_impl->thread_attrs.num_attributes != 0) { |
| 573 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 574 | + "Thread attributes already set: '%s %s'.", argv[i], argv[i + 1]); |
| 575 | + ++i; |
| 576 | + continue; |
| 577 | + } |
| 578 | + // Attempt to parse next argument as thread attribute rule |
| 579 | + if (RCL_RET_OK == |
| 580 | + rcl_parse_yaml_thread_attrs_value(argv[i + 1], &args_impl->thread_attrs)) |
| 581 | + { |
| 582 | + RCUTILS_LOG_DEBUG_NAMED( |
| 583 | + ROS_PACKAGE_NAME, "Got thread attribute rule : %s\n", argv[i + 1]); |
| 584 | + ++i; // Skip flag here, for loop will skip rule. |
| 585 | + continue; |
| 586 | + } |
| 587 | + rcl_error_string_t prev_error_string = rcl_get_error_string(); |
| 588 | + rcl_reset_error(); |
| 589 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 590 | + "Couldn't parse thread attribute rule: '%s %s'. Error: %s", argv[i], argv[i + 1], |
| 591 | + prev_error_string.str); |
| 592 | + } else { |
| 593 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 594 | + "Couldn't parse trailing %s flag. No thread attribute rule found.", argv[i]); |
| 595 | + } |
| 596 | + ret = RCL_RET_INVALID_ROS_ARGS; |
| 597 | + goto fail; |
| 598 | + } |
| 599 | + RCUTILS_LOG_DEBUG_NAMED( |
| 600 | + ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.", |
| 601 | + i, argv[i], RCL_THREAD_ATTRS_VALUE_FLAG); |
| 602 | + |
| 603 | + // Attempt to parse argument as thread attribute file rule |
| 604 | + if (strcmp(RCL_THREAD_ATTRS_FILE_FLAG, argv[i]) == 0) { |
| 605 | + if (i + 1 < argc) { |
| 606 | + if (args_impl->thread_attrs.num_attributes != 0) { |
| 607 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 608 | + "Thread attributes already setted: '%s %s'.", argv[i], argv[i + 1]); |
| 609 | + ++i; |
| 610 | + continue; |
| 611 | + } |
| 612 | + // Attempt to parse next argument as thread attribute file rule |
| 613 | + if ( |
| 614 | + RCL_RET_OK == rcl_parse_yaml_thread_attrs_file( |
| 615 | + argv[i + 1], &args_impl->thread_attrs)) |
| 616 | + { |
| 617 | + ++i; // Skip flag here, for loop will skip rule. |
| 618 | + continue; |
| 619 | + } |
| 620 | + rcl_error_string_t prev_error_string = rcl_get_error_string(); |
| 621 | + rcl_reset_error(); |
| 622 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 623 | + "Couldn't parse thread attr file: '%s %s'. Error: %s", argv[i], argv[i + 1], |
| 624 | + prev_error_string.str); |
| 625 | + } else { |
| 626 | + RCL_SET_ERROR_MSG_WITH_FORMAT_STRING( |
| 627 | + "Couldn't parse trailing %s flag. No file path provided.", argv[i]); |
| 628 | + } |
| 629 | + ret = RCL_RET_INVALID_ROS_ARGS; |
| 630 | + goto fail; |
| 631 | + } |
| 632 | + RCUTILS_LOG_DEBUG_NAMED( |
| 633 | + ROS_PACKAGE_NAME, "Arg %d (%s) is not a %s flag.", |
| 634 | + i, argv[i], RCL_THREAD_ATTRS_FILE_FLAG); |
| 635 | + |
562 | 636 | // Argument is an unknown ROS specific argument |
563 | 637 | args_impl->unparsed_ros_args[args_impl->num_unparsed_ros_args] = i; |
564 | 638 | ++(args_impl->num_unparsed_ros_args); |
@@ -988,6 +1062,14 @@ rcl_arguments_fini( |
988 | 1062 | args->impl->external_log_config_file = NULL; |
989 | 1063 | } |
990 | 1064 |
|
| 1065 | + rcl_ret_t thread_ret = rcl_thread_attrs_fini(&args->impl->thread_attrs); |
| 1066 | + if (thread_ret != RCL_RET_OK) { |
| 1067 | + ret = thread_ret; |
| 1068 | + RCUTILS_LOG_ERROR_NAMED( |
| 1069 | + ROS_PACKAGE_NAME, |
| 1070 | + "Failed to finalize thread attribute while finalizing arguments. Continuing..."); |
| 1071 | + } |
| 1072 | + |
991 | 1073 | args->impl->allocator.deallocate(args->impl, args->impl->allocator.state); |
992 | 1074 | args->impl = NULL; |
993 | 1075 | return ret; |
@@ -2067,11 +2149,29 @@ _rcl_allocate_initialized_arguments_impl(rcl_arguments_t * args, rcl_allocator_t |
2067 | 2149 | args_impl->log_rosout_disabled = false; |
2068 | 2150 | args_impl->log_ext_lib_disabled = false; |
2069 | 2151 | args_impl->enclave = NULL; |
| 2152 | + args_impl->thread_attrs = rcl_get_zero_initialized_thread_attrs(); |
2070 | 2153 | args_impl->allocator = *allocator; |
2071 | 2154 |
|
2072 | 2155 | return RCL_RET_OK; |
2073 | 2156 | } |
2074 | 2157 |
|
| 2158 | +rcl_ret_t |
| 2159 | +rcl_arguments_get_thread_attrs( |
| 2160 | + const rcl_arguments_t * arguments, |
| 2161 | + rcl_thread_attrs_t ** thread_attrs) |
| 2162 | +{ |
| 2163 | + RCL_CHECK_ARGUMENT_FOR_NULL(arguments, RCL_RET_INVALID_ARGUMENT); |
| 2164 | + RCL_CHECK_ARGUMENT_FOR_NULL(arguments->impl, RCL_RET_INVALID_ARGUMENT); |
| 2165 | + RCL_CHECK_ARGUMENT_FOR_NULL(thread_attrs, RCL_RET_INVALID_ARGUMENT); |
| 2166 | + |
| 2167 | + if (0 < arguments->impl->thread_attrs.num_attributes) { |
| 2168 | + *thread_attrs = &arguments->impl->thread_attrs; |
| 2169 | + return RCL_RET_OK; |
| 2170 | + } else { |
| 2171 | + return RCL_RET_ERROR; |
| 2172 | + } |
| 2173 | +} |
| 2174 | + |
2075 | 2175 | #ifdef __cplusplus |
2076 | 2176 | } |
2077 | 2177 | #endif |
|
0 commit comments