Merge branch 'master' into merge2
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
This commit is contained in:
		
						commit
						3fc777e631
					
				
					 477 changed files with 31941 additions and 32175 deletions
				
			
		| 
						 | 
				
			
			@ -10,65 +10,38 @@
 | 
			
		|||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
#
 | 
			
		||||
include(CUnit)
 | 
			
		||||
include(GenerateExportHeader)
 | 
			
		||||
include(GenerateDummyExportHeader)
 | 
			
		||||
 | 
			
		||||
set(sources
 | 
			
		||||
    "atomics.c"
 | 
			
		||||
    "dynlib.c"
 | 
			
		||||
    "environ.c"
 | 
			
		||||
    "heap.c"
 | 
			
		||||
    "ifaddrs.c"
 | 
			
		||||
    "sync.c"
 | 
			
		||||
    "strtoll.c"
 | 
			
		||||
    "thread.c"
 | 
			
		||||
    "thread_cleanup.c"
 | 
			
		||||
    "string.c"
 | 
			
		||||
    "log.c"
 | 
			
		||||
    "random.c"
 | 
			
		||||
    "strlcpy.c"
 | 
			
		||||
    "socket.c"
 | 
			
		||||
    "process.c"
 | 
			
		||||
    "select.c")
 | 
			
		||||
list(APPEND sources
 | 
			
		||||
  "atomics.c"
 | 
			
		||||
  "dynlib.c"
 | 
			
		||||
  "environ.c"
 | 
			
		||||
  "heap.c"
 | 
			
		||||
  "ifaddrs.c"
 | 
			
		||||
  "sync.c"
 | 
			
		||||
  "strtoll.c"
 | 
			
		||||
  "thread.c"
 | 
			
		||||
  "thread_cleanup.c"
 | 
			
		||||
  "string.c"
 | 
			
		||||
  "log.c"
 | 
			
		||||
  "random.c"
 | 
			
		||||
  "strlcpy.c"
 | 
			
		||||
  "socket.c"
 | 
			
		||||
  "select.c")
 | 
			
		||||
 | 
			
		||||
add_cunit_executable(cunit_ddsrt ${sources})
 | 
			
		||||
target_link_libraries(cunit_ddsrt PRIVATE ddsrt)
 | 
			
		||||
 | 
			
		||||
# Create a dummy export header. generate_export_header can only be used with
 | 
			
		||||
# library targets, but since the targets are linked statically,
 | 
			
		||||
# __declspec(dllimport) is not required anyway.
 | 
			
		||||
set(export_dir "${CMAKE_CURRENT_BINARY_DIR}/include/dds")
 | 
			
		||||
set(export_header "${export_dir}/export.h")
 | 
			
		||||
if(NOT EXISTS "${export_header}")
 | 
			
		||||
  file(MAKE_DIRECTORY "${export_dir}")
 | 
			
		||||
  file(WRITE "${export_header}" "#define DDS_EXPORT\n")
 | 
			
		||||
if(HAVE_MULTI_PROCESS)
 | 
			
		||||
  list(APPEND sources "process.c")
 | 
			
		||||
endif()
 | 
			
		||||
if(WITH_FREERTOS)
 | 
			
		||||
  list(APPEND sources "tasklist.c")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_cunit_executable(cunit_ddsrt ${sources})
 | 
			
		||||
target_link_libraries(
 | 
			
		||||
  cunit_ddsrt PRIVATE ddsrt)
 | 
			
		||||
target_include_directories(
 | 
			
		||||
  cunit_ddsrt PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
 | 
			
		||||
 | 
			
		||||
# Create a separate test application that will be used to
 | 
			
		||||
# test process management.
 | 
			
		||||
add_executable(process_app process_app.c)
 | 
			
		||||
target_link_libraries(process_app PRIVATE ddsrt)
 | 
			
		||||
target_include_directories(
 | 
			
		||||
        process_app
 | 
			
		||||
        PRIVATE
 | 
			
		||||
        "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
 | 
			
		||||
# Force the app to be at the same location, no matter what platform or build type.
 | 
			
		||||
set_target_properties(
 | 
			
		||||
        process_app
 | 
			
		||||
        PROPERTIES
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY                ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_DEBUG          ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_RELEASE        ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL     ${CMAKE_CURRENT_BINARY_DIR} )
 | 
			
		||||
# Let the cunit application know the location and name of the test application.
 | 
			
		||||
set(process_app_name "${CMAKE_CURRENT_BINARY_DIR}/process_app${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
configure_file(
 | 
			
		||||
        "process_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/process_test.h" @ONLY)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Create a separate shared library that will be used to
 | 
			
		||||
# test dynamic library loading.
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +62,7 @@ set_target_properties(
 | 
			
		|||
        LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL     ${CMAKE_CURRENT_BINARY_DIR} )
 | 
			
		||||
# Use proper export for this test lib.
 | 
			
		||||
generate_export_header(${test_lib_name} BASE_NAME LIB_TEST)
 | 
			
		||||
#generate_dummy_export_header(${test_lib_name} BASE_NAME dds LIB_TEST)
 | 
			
		||||
target_include_directories(${test_lib_name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
 | 
			
		||||
# Let the cunit application know the location and name of the library.
 | 
			
		||||
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" test_lib_native_dir)
 | 
			
		||||
| 
						 | 
				
			
			@ -112,3 +85,38 @@ foreach(libtest ${test_lib_tests})
 | 
			
		|||
  endif()
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
generate_dummy_export_header(
 | 
			
		||||
  cunit_ddsrt
 | 
			
		||||
  BASE_NAME dds
 | 
			
		||||
  EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/dds/export.h")
 | 
			
		||||
 | 
			
		||||
generate_dummy_export_header(
 | 
			
		||||
  ${test_lib_name}
 | 
			
		||||
  BASE_NAME lib_test
 | 
			
		||||
  EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/lib_test_export.h")
 | 
			
		||||
 | 
			
		||||
if(HAVE_MULTI_PROCESS)
 | 
			
		||||
  # A separate application is required to test process management.
 | 
			
		||||
  add_executable(process_app process_app.c)
 | 
			
		||||
  target_link_libraries(process_app PRIVATE ddsrt)
 | 
			
		||||
  target_include_directories(
 | 
			
		||||
    process_app
 | 
			
		||||
    PRIVATE
 | 
			
		||||
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
 | 
			
		||||
  # Force the app to be at the same location, no matter what platform or build type.
 | 
			
		||||
  # FIXME: What if custom targets are added?
 | 
			
		||||
  # FIXME: What debug and release builds are mixed on Windows and macOS?
 | 
			
		||||
  set_target_properties(
 | 
			
		||||
    process_app
 | 
			
		||||
    PROPERTIES
 | 
			
		||||
    RUNTIME_OUTPUT_DIRECTORY                ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
    RUNTIME_OUTPUT_DIRECTORY_DEBUG          ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
    RUNTIME_OUTPUT_DIRECTORY_RELEASE        ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
    RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
    RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL     ${CMAKE_CURRENT_BINARY_DIR} )
 | 
			
		||||
  # Let the cunit application know the location and name of the test application.
 | 
			
		||||
  set(process_app_name "${CMAKE_CURRENT_BINARY_DIR}/process_app${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
  configure_file(
 | 
			
		||||
    "process_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/process_test.h" @ONLY)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,12 +13,14 @@
 | 
			
		|||
 | 
			
		||||
static int g_val = -1;
 | 
			
		||||
 | 
			
		||||
LIB_TEST_EXPORT void set_int(int val)
 | 
			
		||||
LIB_TEST_EXPORT void set_int(int val);
 | 
			
		||||
void set_int(int val)
 | 
			
		||||
{
 | 
			
		||||
  g_val = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LIB_TEST_EXPORT int get_int(void)
 | 
			
		||||
LIB_TEST_EXPORT int get_int(void);
 | 
			
		||||
int get_int(void)
 | 
			
		||||
{
 | 
			
		||||
  return g_val;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,10 +25,10 @@
 | 
			
		|||
#define TEST_ABORT_IF_NULL(var, msg) \
 | 
			
		||||
do { \
 | 
			
		||||
  if (var == NULL) { \
 | 
			
		||||
    char buffer[256]; \
 | 
			
		||||
    r = ddsrt_dlerror(buffer, sizeof(buffer)); \
 | 
			
		||||
    char err[256]; \
 | 
			
		||||
    r = ddsrt_dlerror(err, sizeof(err)); \
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK); \
 | 
			
		||||
    printf("\n%s", buffer); \
 | 
			
		||||
    printf("\n%s", err); \
 | 
			
		||||
    CU_FAIL_FATAL(msg); \
 | 
			
		||||
  } \
 | 
			
		||||
} while(0)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ do { \
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_path)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t  l;
 | 
			
		||||
 | 
			
		||||
  printf("Absolute lib: %s\n", TEST_LIB_ABSOLUTE);
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ CU_Test(ddsrt_library, dlopen_path)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_file)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_FILE, false, &l);
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ CU_Test(ddsrt_library, dlopen_file)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_name)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ CU_Test(ddsrt_library, dlopen_name)
 | 
			
		|||
CU_Test(ddsrt_library, dlopen_unknown)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[256];
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen("UnknownLib", false, &l);
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ CU_Test(ddsrt_library, dlopen_unknown)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_library, dlsym)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
  void* f;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ CU_Test(ddsrt_library, dlsym)
 | 
			
		|||
CU_Test(ddsrt_library, dlsym_unknown)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[256];
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
  void* f;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ CU_Test(ddsrt_library, call)
 | 
			
		|||
  int set_int = 1234;
 | 
			
		||||
  func_get_int f_get;
 | 
			
		||||
  func_set_int f_set;
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  dds_return_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
| 
						 | 
				
			
			@ -171,7 +171,7 @@ CU_Test(ddsrt_library, call)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_library, dlclose_error)
 | 
			
		||||
{
 | 
			
		||||
    dds_retcode_t r;
 | 
			
		||||
    dds_return_t r;
 | 
			
		||||
    ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
    r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
| 
						 | 
				
			
			@ -189,9 +189,10 @@ CU_Test(ddsrt_library, dlclose_error)
 | 
			
		|||
CU_Test(ddsrt_library, dlerror_notfound)
 | 
			
		||||
{
 | 
			
		||||
    char buffer[256];
 | 
			
		||||
    dds_retcode_t r;
 | 
			
		||||
    dds_return_t r;
 | 
			
		||||
    ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
    r = ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
    CU_ASSERT_EQUAL(r, DDS_RETCODE_NOT_FOUND);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ CU_TheoryDataPoints(ddsrt_environ, bad_name) = {
 | 
			
		|||
 | 
			
		||||
CU_Theory((const char *name), ddsrt_environ, bad_name)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  static const char value[] = "bar";
 | 
			
		||||
  static char dummy[] = "foobar";
 | 
			
		||||
  char *ptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ CU_Theory((const char *name), ddsrt_environ, bad_name)
 | 
			
		|||
DDSRT_WARNING_MSVC_OFF(4996)
 | 
			
		||||
CU_Test(ddsrt_environ, setenv)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  static const char name[] = "foo";
 | 
			
		||||
  static char value[] = "bar";
 | 
			
		||||
  char *ptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ DDSRT_WARNING_MSVC_ON(4996)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_environ, getenv)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  static const char name[] = "foo";
 | 
			
		||||
  static const char value[] = "bar";
 | 
			
		||||
  static char dummy[] = "foobar";
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ CU_TheoryDataPoints(ddsrt_environ, expand) = {
 | 
			
		|||
};
 | 
			
		||||
CU_Theory((const char *var, const char *expect), ddsrt_environ, expand)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  static const char x_name[]  = "X";
 | 
			
		||||
  static const char x_value[] = "TEST";
 | 
			
		||||
  static const char y_name[]  = "Y";
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ CU_Theory((const char *var, const char *expect), ddsrt_environ, expand)
 | 
			
		|||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
 | 
			
		||||
  /* Expand a string with available environment variables. */
 | 
			
		||||
  ptr = ddsrt_expand_envvars(var);
 | 
			
		||||
  ptr = ddsrt_expand_envvars(var,UINT32_MAX);
 | 
			
		||||
  if (ptr) {
 | 
			
		||||
    /* printf("==== %10s: expand(%s), expect(%s))\n", var, ptr, expect); */
 | 
			
		||||
    CU_ASSERT_STRING_EQUAL(ptr, expect);
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ CU_TheoryDataPoints(ddsrt_environ, expand_sh) = {
 | 
			
		|||
};
 | 
			
		||||
CU_Theory((const char *var, const char *expect), ddsrt_environ, expand_sh)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  static const char x_name[]  = "X";
 | 
			
		||||
  static const char x_value[] = "TEST";
 | 
			
		||||
  static const char y_name[]  = "Y";
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +183,7 @@ CU_Theory((const char *var, const char *expect), ddsrt_environ, expand_sh)
 | 
			
		|||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
 | 
			
		||||
  /* Expand a string with available environment variables. */
 | 
			
		||||
  ptr = ddsrt_expand_envvars_sh(var);
 | 
			
		||||
  ptr = ddsrt_expand_envvars_sh(var,UINT32_MAX);
 | 
			
		||||
  if (ptr) {
 | 
			
		||||
    /* printf("==== %10s: expand(%s), expect(%s))\n", var, ptr, expect); */
 | 
			
		||||
    CU_ASSERT_STRING_EQUAL(ptr, expect);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,10 +9,10 @@
 | 
			
		|||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include "CUnit/Test.h"
 | 
			
		||||
#include "dds/ddsrt/cdtors.h"
 | 
			
		||||
#include "dds/ddsrt/ifaddrs.h"
 | 
			
		||||
#include "dds/ddsrt/retcode.h"
 | 
			
		||||
#include "CUnit/Test.h"
 | 
			
		||||
 | 
			
		||||
/* FIXME: It's not possible to predict what network interfaces are available
 | 
			
		||||
          on a given host. To properly test all combinations the abstracted
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ CU_Clean(ddsrt_getifaddrs)
 | 
			
		|||
   IFF_LOOPBACK flags are properly set. */
 | 
			
		||||
CU_Test(ddsrt_getifaddrs, ipv4)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  int seen = 0;
 | 
			
		||||
  ddsrt_ifaddrs_t *ifa_root, *ifa;
 | 
			
		||||
  const int afs[] = { AF_INET, DDSRT_AF_TERM };
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ CU_Test(ddsrt_getifaddrs, ipv4)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_getifaddrs, null_filter)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  int cnt = 0;
 | 
			
		||||
  ddsrt_ifaddrs_t *ifa_root, *ifa;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ CU_Test(ddsrt_getifaddrs, null_filter)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_getifaddrs, empty_filter)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_ifaddrs_t *ifa_root;
 | 
			
		||||
  const int afs[] = { DDSRT_AF_TERM };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -117,11 +117,11 @@ CU_Test(ddsrt_getifaddrs, empty_filter)
 | 
			
		|||
  ddsrt_freeifaddrs(ifa_root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef DDSRT_HAVE_IPV6
 | 
			
		||||
CU_Test(ddsrt_getifaddrs, ipv6)
 | 
			
		||||
{
 | 
			
		||||
#ifdef DDSRT_HAVE_IPV6
 | 
			
		||||
  if (ipv6_enabled == 1) {
 | 
			
		||||
    dds_retcode_t ret;
 | 
			
		||||
    dds_return_t ret;
 | 
			
		||||
    int have_ipv6 = 0;
 | 
			
		||||
    ddsrt_ifaddrs_t *ifa_root, *ifa;
 | 
			
		||||
    const int afs[] = { AF_INET6, DDSRT_AF_TERM };
 | 
			
		||||
| 
						 | 
				
			
			@ -149,14 +149,18 @@ CU_Test(ddsrt_getifaddrs, ipv6)
 | 
			
		|||
  } else {
 | 
			
		||||
    CU_PASS("IPv6 disabled in test environment");
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  CU_PASS("IPv6 is not supported");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assume at least one IPv4 and one IPv6 interface are available when IPv6 is
 | 
			
		||||
   available on the platform. */
 | 
			
		||||
CU_Test(ddsrt_getifaddrs, ipv4_n_ipv6)
 | 
			
		||||
{
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
  if (ipv6_enabled == 1) {
 | 
			
		||||
    dds_retcode_t ret;
 | 
			
		||||
    dds_return_t ret;
 | 
			
		||||
    int have_ipv4 = 0;
 | 
			
		||||
    int have_ipv6 = 0;
 | 
			
		||||
    ddsrt_ifaddrs_t *ifa_root, *ifa;
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +186,8 @@ CU_Test(ddsrt_getifaddrs, ipv4_n_ipv6)
 | 
			
		|||
  } else {
 | 
			
		||||
    CU_PASS("IPv6 disabled in test environment");
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  CU_PASS("IPv6 is not supported");
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -311,8 +311,8 @@ static ddsrt_mutex_t mutex;
 | 
			
		|||
struct arg {
 | 
			
		||||
  ddsrt_cond_t *cond;
 | 
			
		||||
  ddsrt_mutex_t *mutex;
 | 
			
		||||
  dds_time_t stamp;
 | 
			
		||||
  dds_duration_t pause;
 | 
			
		||||
  dds_time_t before;
 | 
			
		||||
  dds_time_t after;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void dummy(void *ptr, const dds_log_data_t *data)
 | 
			
		||||
| 
						 | 
				
			
			@ -326,10 +326,10 @@ static void block(void *ptr, const dds_log_data_t *data)
 | 
			
		|||
  (void)data;
 | 
			
		||||
  struct arg *arg = (struct arg *)ptr;
 | 
			
		||||
  ddsrt_mutex_lock(arg->mutex);
 | 
			
		||||
  arg->stamp = dds_time();
 | 
			
		||||
  arg->before = dds_time();
 | 
			
		||||
  ddsrt_cond_broadcast(arg->cond);
 | 
			
		||||
  ddsrt_mutex_unlock(arg->mutex);
 | 
			
		||||
  dds_sleepfor(arg->pause);
 | 
			
		||||
  arg->after = dds_time();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t run(void *ptr)
 | 
			
		||||
| 
						 | 
				
			
			@ -347,17 +347,15 @@ static uint32_t run(void *ptr)
 | 
			
		|||
CU_Test(dds_log, synchronous_sink_changes, .fini=reset)
 | 
			
		||||
{
 | 
			
		||||
  struct arg arg;
 | 
			
		||||
  dds_time_t diff, stamp;
 | 
			
		||||
  ddsrt_thread_t tid;
 | 
			
		||||
  ddsrt_threadattr_t tattr;
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_init(&mutex);
 | 
			
		||||
  ddsrt_cond_init(&cond);
 | 
			
		||||
  (void)memset(&arg, 0, sizeof(arg));
 | 
			
		||||
  arg.mutex = &mutex;
 | 
			
		||||
  arg.cond = &cond;
 | 
			
		||||
  arg.pause = 1000000;
 | 
			
		||||
 | 
			
		||||
  ddsrt_mutex_lock(&mutex);
 | 
			
		||||
  dds_set_log_sink(&block, &arg);
 | 
			
		||||
| 
						 | 
				
			
			@ -366,9 +364,7 @@ CU_Test(dds_log, synchronous_sink_changes, .fini=reset)
 | 
			
		|||
  CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
 | 
			
		||||
  ddsrt_cond_wait(&cond, &mutex);
 | 
			
		||||
  dds_set_log_sink(dummy, NULL);
 | 
			
		||||
  stamp = dds_time();
 | 
			
		||||
 | 
			
		||||
  CU_ASSERT(arg.stamp < stamp);
 | 
			
		||||
  diff = stamp - arg.stamp;
 | 
			
		||||
  CU_ASSERT(arg.pause < diff);
 | 
			
		||||
  CU_ASSERT(arg.before < arg.after);
 | 
			
		||||
  CU_ASSERT(arg.after < dds_time());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@
 | 
			
		|||
 */
 | 
			
		||||
static void create_and_test_exit(const char *arg, int code)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
  int32_t status;
 | 
			
		||||
  char *argv[] = { NULL, NULL };
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ CU_Test(ddsrt_process, create)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, kill)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
 | 
			
		||||
  /* Sleep for 20 seconds. It should be killed before then. */
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ CU_Test(ddsrt_process, kill)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, pid)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
  int32_t status;
 | 
			
		||||
  char *argv[] = { TEST_PID_ARG, NULL };
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ CU_Test(ddsrt_process, pid)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, env)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
 | 
			
		||||
  ret = ddsrt_setenv(TEST_ENV_VAR_NAME, TEST_ENV_VAR_VALUE);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(ret, DDS_RETCODE_OK);
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ CU_Test(ddsrt_process, env)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, invalid)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
 | 
			
		||||
  ret = ddsrt_proc_create("ProbablyNotAnValidExecutable", NULL, &pid);
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ CU_Test(ddsrt_process, arg_dquote)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, waitpids)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t child;
 | 
			
		||||
  ddsrt_pid_t pid1 = 0;
 | 
			
		||||
  ddsrt_pid_t pid2 = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,7 @@ CU_Test(ddsrt_process, waitpids)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, waitpid_timeout)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
 | 
			
		||||
  /* Sleep for 20 seconds. We should have a timeout before then. */
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ CU_Test(ddsrt_process, waitpid_timeout)
 | 
			
		|||
  ret = ddsrt_proc_waitpid(pid, 0, NULL);
 | 
			
		||||
  CU_ASSERT_EQUAL(ret, DDS_RETCODE_PRECONDITION_NOT_MET);
 | 
			
		||||
 | 
			
		||||
  /* Valid timeout should return DDS_RETCODE_TIMEOUT when alive. */
 | 
			
		||||
  /* Valid timeout should return DDS_RETURN_TIMEOUT when alive. */
 | 
			
		||||
  ret = ddsrt_proc_waitpid(pid, DDS_SECS(1), NULL);
 | 
			
		||||
  CU_ASSERT_EQUAL(ret, DDS_RETCODE_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +257,7 @@ CU_Test(ddsrt_process, waitpid_timeout)
 | 
			
		|||
 */
 | 
			
		||||
CU_Test(ddsrt_process, waitpids_timeout)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_pid_t pid;
 | 
			
		||||
 | 
			
		||||
  /* Sleep for 20 seconds. We should have a timeout before then. */
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +270,7 @@ CU_Test(ddsrt_process, waitpids_timeout)
 | 
			
		|||
  ret = ddsrt_proc_waitpids(0, NULL, NULL);
 | 
			
		||||
  CU_ASSERT_EQUAL(ret, DDS_RETCODE_PRECONDITION_NOT_MET);
 | 
			
		||||
 | 
			
		||||
  /* Valid timeout should return DDS_RETCODE_TIMEOUT when alive. */
 | 
			
		||||
  /* Valid timeout should return DDS_RETURN_TIMEOUT when alive. */
 | 
			
		||||
  ret = ddsrt_proc_waitpids(DDS_SECS(1), NULL, NULL);
 | 
			
		||||
  CU_ASSERT_EQUAL(ret, DDS_RETCODE_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,10 +9,10 @@
 | 
			
		|||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
#include "dds/ddsrt/cdtors.h"
 | 
			
		||||
#include "dds/ddsrt/sockets_priv.h"
 | 
			
		||||
#include "dds/ddsrt/cdtors.h"
 | 
			
		||||
#include "dds/ddsrt/threads.h"
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
 | 
			
		||||
CU_Init(ddsrt_select)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -36,8 +36,13 @@ CU_Test(ddsrt_select, duration_to_timeval)
 | 
			
		|||
{
 | 
			
		||||
  struct timeval tv, *tvptr;
 | 
			
		||||
  dds_duration_t nsecs_max;
 | 
			
		||||
  dds_duration_t secs_max = DDSRT_MAX_INTEGER(ddsrt_tv_sec_t);
 | 
			
		||||
  dds_duration_t usecs_max = 999999;
 | 
			
		||||
  dds_duration_t secs_max;
 | 
			
		||||
  DDSRT_STATIC_ASSERT (CHAR_BIT * sizeof (ddsrt_tv_sec_t) == 32 || CHAR_BIT * sizeof (ddsrt_tv_sec_t) == 64);
 | 
			
		||||
  if (CHAR_BIT * sizeof (ddsrt_tv_sec_t) == 32)
 | 
			
		||||
    secs_max = INT32_MAX;
 | 
			
		||||
  else
 | 
			
		||||
    secs_max = INT64_MAX;
 | 
			
		||||
 | 
			
		||||
  if (DDS_INFINITY > secs_max) {
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(secs_max, INT32_MAX);
 | 
			
		||||
| 
						 | 
				
			
			@ -107,40 +112,45 @@ typedef struct {
 | 
			
		|||
static void
 | 
			
		||||
sockets_pipe(ddsrt_socket_t socks[2])
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_socket_t sock;
 | 
			
		||||
  int reuseaddr = 1;
 | 
			
		||||
 | 
			
		||||
  socklen_t addrlen;
 | 
			
		||||
  struct sockaddr_in addr;
 | 
			
		||||
  addr.sin_family = AF_INET;
 | 
			
		||||
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 | 
			
		||||
  addr.sin_port = htons(54321);
 | 
			
		||||
  addr.sin_port = 0;
 | 
			
		||||
 | 
			
		||||
  fprintf (stderr, "sockets_pipe ... begin\n");
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL_FATAL(socks);
 | 
			
		||||
  rc = ddsrt_socket(&sock, AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  rc = ddsrt_setsockopt(
 | 
			
		||||
    sock, SOL_SOCKET, SO_REUSEADDR, (void*)&reuseaddr, sizeof(reuseaddr));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  rc = ddsrt_socket(&socks[1], AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  rc = ddsrt_bind(sock, (struct sockaddr *)&addr, sizeof(addr));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  addrlen = (socklen_t) sizeof(addr);
 | 
			
		||||
  rc = ddsrt_getsockname(sock, (struct sockaddr *)&addr, &addrlen);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  fprintf (stderr, "sockets_pipe ... listen\n");
 | 
			
		||||
  rc = ddsrt_listen(sock, 1);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  fprintf (stderr, "sockets_pipe ... connect\n");
 | 
			
		||||
  rc = ddsrt_connect(socks[1], (struct sockaddr *)&addr, sizeof(addr));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  fprintf (stderr, "sockets_pipe ... accept\n");
 | 
			
		||||
  rc = ddsrt_accept(sock, NULL, NULL, &socks[0]);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  ddsrt_close(sock);
 | 
			
		||||
  fprintf (stderr, "sockets_pipe ... done\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char mesg[] = "foobar";
 | 
			
		||||
 | 
			
		||||
static uint32_t select_timeout_routine(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
  int cnt = -1;
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  int32_t cnt = -1;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  dds_time_t before, after;
 | 
			
		||||
  dds_duration_t delay;
 | 
			
		||||
  fd_set rdset;
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +158,13 @@ static uint32_t select_timeout_routine(void *ptr)
 | 
			
		|||
  uint32_t res = 0;
 | 
			
		||||
 | 
			
		||||
  FD_ZERO(&rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_OFF(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
  FD_SET(arg->sock, &rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_ON(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  before = dds_time();
 | 
			
		||||
  rc = ddsrt_select(arg->sock + 1, &rdset, NULL, NULL, arg->delay, &cnt);
 | 
			
		||||
| 
						 | 
				
			
			@ -157,11 +173,15 @@ static uint32_t select_timeout_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
  fprintf(stderr, "Waited for %"PRId64" (nanoseconds)\n", delay);
 | 
			
		||||
  fprintf(stderr, "Expected to wait %"PRId64" (nanoseconds)\n", arg->delay);
 | 
			
		||||
  fprintf(stderr, "ddsrt_select returned %d\n", rc);
 | 
			
		||||
  fprintf(stderr, "ddsrt_select reported %d ready\n", cnt);
 | 
			
		||||
  fprintf(stderr, "ddsrt_select returned %"PRId32"\n", rc);
 | 
			
		||||
  fprintf(stderr, "ddsrt_select reported %"PRId32" ready\n", cnt);
 | 
			
		||||
 | 
			
		||||
  if (rc == DDS_RETCODE_TIMEOUT) {
 | 
			
		||||
    res = (((after - delay) >= (arg->delay - arg->skew)) && (cnt == 0));
 | 
			
		||||
  /* Running in the FreeRTOS simulator causes some trouble as interrupts are
 | 
			
		||||
     simulated using signals causing the select call to be interrupted. */
 | 
			
		||||
  } else if (rc == DDS_RETCODE_INTERRUPTED) {
 | 
			
		||||
    res = (cnt == -1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +189,7 @@ static uint32_t select_timeout_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_select, timeout)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_socket_t socks[2];
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
| 
						 | 
				
			
			@ -178,23 +198,26 @@ CU_Test(ddsrt_select, timeout)
 | 
			
		|||
 | 
			
		||||
  sockets_pipe(socks);
 | 
			
		||||
 | 
			
		||||
  arg.delay = DDS_MSECS(100);
 | 
			
		||||
  arg.delay = DDS_MSECS(300);
 | 
			
		||||
  /* Allow the delay to be off by x microseconds (arbitrarily chosen) for
 | 
			
		||||
     systems with a really poor clock. This test is just to get some
 | 
			
		||||
     confidence that time calculation is not completely broken, it is by
 | 
			
		||||
     no means proof that time calculation is entirely correct! */
 | 
			
		||||
  arg.skew = DDS_MSECS(20);
 | 
			
		||||
  arg.skew = DDS_MSECS(50);
 | 
			
		||||
  arg.sock = socks[0];
 | 
			
		||||
 | 
			
		||||
  fprintf (stderr, "create thread\n");
 | 
			
		||||
  ddsrt_threadattr_init(&attr);
 | 
			
		||||
  rc = ddsrt_thread_create(&thr, "select_timeout", &attr, &select_timeout_routine, &arg);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  /* Allow the thread some time to get ready. */
 | 
			
		||||
  dds_sleepfor(arg.delay * 2);
 | 
			
		||||
  /* Send data to the read socket to avoid blocking indefinitely. */
 | 
			
		||||
  fprintf (stderr, "write data\n");
 | 
			
		||||
  ssize_t sent = 0;
 | 
			
		||||
  rc = ddsrt_send(socks[1], mesg, sizeof(mesg), 0, &sent);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  fprintf (stderr, "join thread\n");
 | 
			
		||||
  rc = ddsrt_thread_join(thr, &res);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_EQUAL(res, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -207,13 +230,19 @@ static uint32_t recv_routine(void *ptr)
 | 
			
		|||
{
 | 
			
		||||
  thread_arg_t *arg = (thread_arg_t*)ptr;
 | 
			
		||||
 | 
			
		||||
  int nfds = 0;
 | 
			
		||||
  int32_t nfds = 0;
 | 
			
		||||
  fd_set rdset;
 | 
			
		||||
  ssize_t rcvd = -1;
 | 
			
		||||
  char buf[sizeof(mesg)];
 | 
			
		||||
 | 
			
		||||
  FD_ZERO(&rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_OFF(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
  FD_SET(arg->sock, &rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_ON(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  (void)ddsrt_select(arg->sock + 1, &rdset, NULL, NULL, arg->delay, &nfds);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +255,7 @@ static uint32_t recv_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_select, send_recv)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_socket_t socks[2];
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +289,7 @@ static uint32_t recvmsg_routine(void *ptr)
 | 
			
		|||
{
 | 
			
		||||
  thread_arg_t *arg = (thread_arg_t*)ptr;
 | 
			
		||||
 | 
			
		||||
  int nfds = 0;
 | 
			
		||||
  int32_t nfds = 0;
 | 
			
		||||
  fd_set rdset;
 | 
			
		||||
  ssize_t rcvd = -1;
 | 
			
		||||
  char buf[sizeof(mesg)];
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +303,13 @@ static uint32_t recvmsg_routine(void *ptr)
 | 
			
		|||
  msg.msg_iovlen = 1;
 | 
			
		||||
 | 
			
		||||
  FD_ZERO(&rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_OFF(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
  FD_SET(arg->sock, &rdset);
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  DDSRT_WARNING_GNUC_ON(sign-conversion)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  (void)ddsrt_select(arg->sock + 1, &rdset, NULL, NULL, arg->delay, &nfds);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +322,7 @@ static uint32_t recvmsg_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_select, sendmsg_recvmsg)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_socket_t socks[2];
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,17 +9,17 @@
 | 
			
		|||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
#include "dds/ddsrt/sockets.h"
 | 
			
		||||
#include "dds/ddsrt/cdtors.h"
 | 
			
		||||
#include "dds/ddsrt/endian.h"
 | 
			
		||||
#include "dds/ddsrt/heap.h"
 | 
			
		||||
#include "dds/ddsrt/misc.h"
 | 
			
		||||
#include "dds/ddsrt/sockets.h"
 | 
			
		||||
#include "dds/ddsrt/string.h"
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
DDSRT_WARNING_MSVC_OFF(4305)
 | 
			
		||||
#if DDSRT_ENDIAN == DDSRT_BIG_ENDIAN
 | 
			
		||||
| 
						 | 
				
			
			@ -48,15 +48,15 @@ static void teardown(void)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sockaddrfromstr, bad_family)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  struct sockaddr_storage sa;
 | 
			
		||||
  rc = ddsrt_sockaddrfromstr(AF_UNSPEC, "127.0.0.1", &sa);
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, DDS_RETCODE_BAD_PARAMETER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sockaddrfromstr_test(char *str, int af, dds_retcode_t exp)
 | 
			
		||||
static void sockaddrfromstr_test(char *str, int af, dds_return_t exp)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  struct sockaddr_storage ss;
 | 
			
		||||
  rc = ddsrt_sockaddrfromstr(af, str, &ss);
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, exp);
 | 
			
		||||
| 
						 | 
				
			
			@ -70,37 +70,44 @@ CU_TheoryDataPoints(ddsrt_sockaddrfromstr, ipv4) = {
 | 
			
		|||
                        "nip"),
 | 
			
		||||
  CU_DataPoints(int, AF_INET, AF_INET,
 | 
			
		||||
                     AF_INET),
 | 
			
		||||
  CU_DataPoints(dds_retcode_t, DDS_RETCODE_OK, DDS_RETCODE_OK,
 | 
			
		||||
  CU_DataPoints(dds_return_t, DDS_RETCODE_OK, DDS_RETCODE_OK,
 | 
			
		||||
                               DDS_RETCODE_BAD_PARAMETER)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CU_Theory((char *str, int af, dds_retcode_t exp), ddsrt_sockaddrfromstr, ipv4, .init=setup, .fini=teardown)
 | 
			
		||||
CU_Theory((char *str, int af, dds_return_t exp), ddsrt_sockaddrfromstr, ipv4, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
  sockaddrfromstr_test(str, af, exp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
CU_TheoryDataPoints(ddsrt_sockaddrfromstr, ipv6) = {
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
  CU_DataPoints(char *, "127.0.0.1", "::1",
 | 
			
		||||
                        "::1",       "::",
 | 
			
		||||
                        "nip"),
 | 
			
		||||
  CU_DataPoints(int, AF_INET6, AF_INET6,
 | 
			
		||||
                     AF_INET,  AF_INET6,
 | 
			
		||||
                     AF_INET6),
 | 
			
		||||
  CU_DataPoints(dds_retcode_t, DDS_RETCODE_BAD_PARAMETER, DDS_RETCODE_OK,
 | 
			
		||||
  CU_DataPoints(dds_return_t, DDS_RETCODE_BAD_PARAMETER, DDS_RETCODE_OK,
 | 
			
		||||
                               DDS_RETCODE_BAD_PARAMETER, DDS_RETCODE_OK,
 | 
			
		||||
                               DDS_RETCODE_BAD_PARAMETER)
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CU_Theory((char *str, int af, dds_retcode_t exp), ddsrt_sockaddrfromstr, ipv6, .init=setup, .fini=teardown)
 | 
			
		||||
CU_Theory((char *str, int af, dds_return_t exp), ddsrt_sockaddrfromstr, ipv6, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
  sockaddrfromstr_test(str, af, exp);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
  (void)str;
 | 
			
		||||
  (void)af;
 | 
			
		||||
  (void)exp;
 | 
			
		||||
  CU_PASS("IPV6 is not supported");
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sockaddrtostr, bad_sockaddr, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  char buf[128] = { 0 };
 | 
			
		||||
  struct sockaddr_in sa;
 | 
			
		||||
  memcpy(&sa, &ipv4_loopback, sizeof(ipv4_loopback));
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +118,7 @@ CU_Test(ddsrt_sockaddrtostr, bad_sockaddr, .init=setup, .fini=teardown)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sockaddrtostr, no_space, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  char buf[1] = { 0 };
 | 
			
		||||
  rc = ddsrt_sockaddrtostr(&ipv4_loopback, buf, sizeof(buf));
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, DDS_RETCODE_NOT_ENOUGH_SPACE);
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +126,7 @@ CU_Test(ddsrt_sockaddrtostr, no_space, .init=setup, .fini=teardown)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sockaddrtostr, ipv4)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  char buf[128] = { 0 };
 | 
			
		||||
  rc = ddsrt_sockaddrtostr(&ipv4_loopback, buf, sizeof(buf));
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
| 
						 | 
				
			
			@ -128,17 +135,20 @@ CU_Test(ddsrt_sockaddrtostr, ipv4)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sockaddrtostr, ipv6)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  char buf[128] = { 0 };
 | 
			
		||||
  rc = ddsrt_sockaddrtostr(&ipv6_loopback, buf, sizeof(buf));
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_STRING_EQUAL(buf, "::1");
 | 
			
		||||
#else
 | 
			
		||||
  CU_PASS("IPv6 is not supported");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sockets, gethostname)
 | 
			
		||||
{
 | 
			
		||||
  int ret;
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  char sysbuf[200], buf[200];
 | 
			
		||||
 | 
			
		||||
  buf[0] = '\0';
 | 
			
		||||
| 
						 | 
				
			
			@ -146,8 +156,12 @@ CU_Test(ddsrt_sockets, gethostname)
 | 
			
		|||
  CU_ASSERT_EQUAL(rc, DDS_RETCODE_OK);
 | 
			
		||||
 | 
			
		||||
  sysbuf[0] = '\0';
 | 
			
		||||
  ret = gethostname(sysbuf, sizeof(sysbuf));
 | 
			
		||||
#if LWIP_SOCKET
 | 
			
		||||
  ddsrt_strlcpy(sysbuf, "localhost", sizeof(sysbuf));
 | 
			
		||||
#else
 | 
			
		||||
  int ret = gethostname(sysbuf, sizeof(sysbuf));
 | 
			
		||||
  CU_ASSERT_EQUAL(ret, 0);
 | 
			
		||||
#endif
 | 
			
		||||
  CU_ASSERT(strcmp(buf, sysbuf) == 0);
 | 
			
		||||
 | 
			
		||||
  rc = ddsrt_gethostname(buf, strlen(buf) - 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -155,9 +169,9 @@ CU_Test(ddsrt_sockets, gethostname)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#if DDSRT_HAVE_DNS
 | 
			
		||||
static void gethostbyname_test(char *name, int af, dds_retcode_t exp)
 | 
			
		||||
static void gethostbyname_test(char *name, int af, dds_return_t exp)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_hostent_t *hent = NULL;
 | 
			
		||||
  rc = ddsrt_gethostbyname(name, af, &hent);
 | 
			
		||||
  CU_ASSERT_EQUAL(rc, exp);
 | 
			
		||||
| 
						 | 
				
			
			@ -169,30 +183,44 @@ static void gethostbyname_test(char *name, int af, dds_retcode_t exp)
 | 
			
		|||
  }
 | 
			
		||||
  ddsrt_free(hent);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CU_TheoryDataPoints(ddsrt_gethostbyname, ipv4) = {
 | 
			
		||||
  CU_DataPoints(char *,        "",                         "127.0.0.1",    "127.0.0.1"),
 | 
			
		||||
  CU_DataPoints(int,           AF_UNSPEC,                  AF_INET,        AF_UNSPEC),
 | 
			
		||||
  CU_DataPoints(dds_retcode_t, DDS_RETCODE_HOST_NOT_FOUND, DDS_RETCODE_OK, DDS_RETCODE_OK)
 | 
			
		||||
  CU_DataPoints(dds_return_t, DDS_RETCODE_HOST_NOT_FOUND, DDS_RETCODE_OK, DDS_RETCODE_OK)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CU_Theory((char *name, int af, dds_retcode_t exp), ddsrt_gethostbyname, ipv4, .init=setup, .fini=teardown)
 | 
			
		||||
CU_Theory((char *name, int af, dds_return_t exp), ddsrt_gethostbyname, ipv4, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
#if DDSRT_HAVE_DNS
 | 
			
		||||
  gethostbyname_test(name, af, exp);
 | 
			
		||||
#else
 | 
			
		||||
  (void)name;
 | 
			
		||||
  (void)af;
 | 
			
		||||
  (void)exp;
 | 
			
		||||
  CU_PASS("DNS is not supported");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if DDSRT_HAVE_IPV6
 | 
			
		||||
/* Lookup of IPv4 address and specifying AF_INET6 is not invalid as it may
 | 
			
		||||
   return an IPV4-mapped IPv6 address. */
 | 
			
		||||
CU_TheoryDataPoints(ddsrt_gethostbyname, ipv6) = {
 | 
			
		||||
#if DDSRT_HAVE_IPV6 && DDSRT_HAVE_DNS
 | 
			
		||||
  CU_DataPoints(char *,        "::1",                      "::1",          "::1"),
 | 
			
		||||
  CU_DataPoints(int,           AF_INET,                    AF_INET6,       AF_UNSPEC),
 | 
			
		||||
  CU_DataPoints(dds_retcode_t, DDS_RETCODE_HOST_NOT_FOUND, DDS_RETCODE_OK, DDS_RETCODE_OK)
 | 
			
		||||
  CU_DataPoints(dds_return_t, DDS_RETCODE_HOST_NOT_FOUND, DDS_RETCODE_OK, DDS_RETCODE_OK)
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CU_Theory((char *name, int af, dds_retcode_t exp), ddsrt_gethostbyname, ipv6, .init=setup, .fini=teardown)
 | 
			
		||||
CU_Theory((char *name, int af, dds_return_t exp), ddsrt_gethostbyname, ipv6, .init=setup, .fini=teardown)
 | 
			
		||||
{
 | 
			
		||||
#if DDSRT_HAVE_IPV6 && DDSRT_HAVE_DNS
 | 
			
		||||
  gethostbyname_test(name, af, exp);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
  (void)name;
 | 
			
		||||
  (void)af;
 | 
			
		||||
  (void)exp;
 | 
			
		||||
  CU_PASS("DNS and IPv6 are not supported");
 | 
			
		||||
#endif /* DDSRT_HAVE_IPV6 */
 | 
			
		||||
#endif /* DDSRT_HAVE_DNS */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,35 +67,3 @@ CU_Theory((const char *s1, const char *s2, size_t n, eq_t e), ddsrt_strncasecmp,
 | 
			
		|||
  CU_ASSERT((e == eq && r == 0) || (e == lt && r < 0) || (e == gt && r > 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_string, strtok_r)
 | 
			
		||||
{
 | 
			
		||||
  char *res;
 | 
			
		||||
  char *saveptr;
 | 
			
		||||
  char ts1[] = "123,234";
 | 
			
		||||
  char ts2[] = ",;,123abc,,456,:,";
 | 
			
		||||
  char ts3[] = ",,,123,,456,789,,,";
 | 
			
		||||
 | 
			
		||||
  res = ddsrt_strtok_r(ts1, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "123") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "234") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(res == NULL);
 | 
			
		||||
 | 
			
		||||
  res = ddsrt_strtok_r(ts2, ",;", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "123abc") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "456") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",:", &saveptr);
 | 
			
		||||
  CU_ASSERT(res == NULL);
 | 
			
		||||
 | 
			
		||||
  res = ddsrt_strtok_r(ts3, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "123") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "456") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",", &saveptr);
 | 
			
		||||
  CU_ASSERT(strcmp(res, "789") == 0);
 | 
			
		||||
  res = ddsrt_strtok_r( NULL, ",:", &saveptr);
 | 
			
		||||
  CU_ASSERT(res == NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,9 +27,9 @@ char str_xllmin[99], str_xllmax[99];
 | 
			
		|||
 | 
			
		||||
/* Really test with the maximum values supported on a platform, not some
 | 
			
		||||
   made up number. */
 | 
			
		||||
long long llmin = DDSRT_MIN_INTEGER(long long);
 | 
			
		||||
long long llmax = DDSRT_MAX_INTEGER(long long);
 | 
			
		||||
unsigned long long ullmax = DDSRT_MAX_INTEGER(unsigned long long);
 | 
			
		||||
long long llmin = INT64_MIN;
 | 
			
		||||
long long llmax = INT64_MAX;
 | 
			
		||||
unsigned long long ullmax = UINT64_MAX;
 | 
			
		||||
 | 
			
		||||
CU_Init(ddsrt_strtoll)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ CU_Clean(ddstr_strtoll)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_strtoll, strtoll)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  long long ll;
 | 
			
		||||
  static char dummy[] = "dummy";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +248,7 @@ CU_Test(ddsrt_strtoll, strtoll)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_strtoll, strtoull)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  unsigned long long ull;
 | 
			
		||||
 | 
			
		||||
  str = "0xffffffffffffffff";
 | 
			
		||||
| 
						 | 
				
			
			@ -272,7 +272,7 @@ CU_Test(ddsrt_strtoll, strtoull)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_strtoll, atoll)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  long long ll;
 | 
			
		||||
 | 
			
		||||
  str = "10";
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +284,7 @@ CU_Test(ddsrt_strtoll, atoll)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_strtoll, atoull)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  unsigned long long ull;
 | 
			
		||||
 | 
			
		||||
  str = "10";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ static uint32_t mutex_lock_routine(void *ptr)
 | 
			
		|||
   main thread before a lock operation is attempted by the second thread. */
 | 
			
		||||
CU_Test(ddsrt_sync, mutex_lock_conc)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  thread_arg_t arg = { .cnt = DDSRT_ATOMIC_UINT32_INIT(0) };
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ static uint32_t rwlock_trywrite_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sync, mutex_trylock_conc)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  thread_arg_t arg = { .cnt = DDSRT_ATOMIC_UINT32_INIT(1) };
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +164,7 @@ CU_TheoryDataPoints(ddsrt_sync, rwlock_trylock_conc) = {
 | 
			
		|||
 | 
			
		||||
CU_Theory((uint32_t lock, uint32_t trylock, uint32_t exp), ddsrt_sync, rwlock_trylock_conc)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  ddsrt_thread_routine_t func;
 | 
			
		||||
| 
						 | 
				
			
			@ -219,7 +219,7 @@ static uint32_t once_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sync, once_conc)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thrs[ONCE_THREADS];
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  uint32_t res;
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +270,7 @@ static uint32_t waitfor_routine(void *ptr)
 | 
			
		|||
  reltime = after - before;
 | 
			
		||||
  fprintf(stderr, "waited for %"PRId64" (nanoseconds)\n", reltime);
 | 
			
		||||
  fprintf(stderr, "expected to wait %"PRId64" (nanoseconds)\n", arg->reltime);
 | 
			
		||||
  fprintf(stderr, "woke up %u times\n", cnt);
 | 
			
		||||
  fprintf(stderr, "woke up %"PRIu32" times\n", cnt);
 | 
			
		||||
  ddsrt_mutex_unlock(&arg->lock);
 | 
			
		||||
  if (reltime >= arg->reltime) {
 | 
			
		||||
    /* Ensure that the condition variable at least waited for the amount of
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +284,7 @@ static uint32_t waitfor_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sync, cond_waitfor)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  thread_arg_t arg = { .cnt = DDSRT_ATOMIC_UINT32_INIT(0), .reltime = DDS_MSECS(100) };
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +322,7 @@ static uint32_t waituntil_routine(void *ptr)
 | 
			
		|||
  ddsrt_mutex_unlock(&arg->lock);
 | 
			
		||||
  fprintf(stderr, "waited until %"PRId64" (nanoseconds)\n", after);
 | 
			
		||||
  fprintf(stderr, "expected to wait until %"PRId64" (nanoseconds)\n", arg->abstime);
 | 
			
		||||
  fprintf(stderr, "woke up %u times\n", cnt);
 | 
			
		||||
  fprintf(stderr, "woke up %"PRIu32" times\n", cnt);
 | 
			
		||||
  if (after > arg->abstime) {
 | 
			
		||||
    res = cnt < 3; /* An arbitrary number to ensure the implementation
 | 
			
		||||
                      did not just spin, aka is completely broken. */
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +333,7 @@ static uint32_t waituntil_routine(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_sync, cond_waituntil)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  dds_duration_t delay = DDS_MSECS(100);
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										341
									
								
								src/ddsrt/tests/tasklist.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								src/ddsrt/tests/tasklist.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,341 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include "dds/ddsrt/sync.h"
 | 
			
		||||
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
 | 
			
		||||
/* FreeRTOS specific! */
 | 
			
		||||
 | 
			
		||||
static void fill(ddsrt_tasklist_t *list)
 | 
			
		||||
{
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL_FATAL(list);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
 | 
			
		||||
  for (size_t i = 1; i <= DDSRT_TASKLIST_INITIAL; i++) {
 | 
			
		||||
    ddsrt_tasklist_push(list, (TaskHandle_t)i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->cnt, i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->off, 0);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->end, i - 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->cnt, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void fill_wrapped(ddsrt_tasklist_t *list)
 | 
			
		||||
{
 | 
			
		||||
  size_t i;
 | 
			
		||||
 | 
			
		||||
  fill(list);
 | 
			
		||||
 | 
			
		||||
  for (i = 1; i <= DDSRT_TASKLIST_CHUNK; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(list, NULL);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->cnt, DDSRT_TASKLIST_INITIAL - i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->off, i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (i = (DDSRT_TASKLIST_INITIAL+1); i <= (DDSRT_TASKLIST_INITIAL+DDSRT_TASKLIST_CHUNK); i++) {
 | 
			
		||||
    ddsrt_tasklist_push(list, (TaskHandle_t)i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->cnt, i - DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(list->end, (i - 1) - DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->cnt, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(list->end, DDSRT_TASKLIST_CHUNK - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef void(*fill_t)(ddsrt_tasklist_t *);
 | 
			
		||||
 | 
			
		||||
CU_TheoryDataPoints(ddsrt_sync, tasklist_pop_all) = {
 | 
			
		||||
  CU_DataPoints(fill_t, &fill, &fill_wrapped),
 | 
			
		||||
  CU_DataPoints(size_t, 1, DDSRT_TASKLIST_CHUNK + 1),
 | 
			
		||||
  CU_DataPoints(size_t, DDSRT_TASKLIST_INITIAL, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Most basic test to verify behavior is correct for simple use case. */
 | 
			
		||||
CU_Theory((fill_t func, size_t first, size_t last), ddsrt_sync, tasklist_pop_all)
 | 
			
		||||
{
 | 
			
		||||
  TaskHandle_t task;
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  func(&list);
 | 
			
		||||
 | 
			
		||||
  task = ddsrt_tasklist_pop(&list, NULL);
 | 
			
		||||
  CU_ASSERT_PTR_EQUAL(task, (TaskHandle_t)first);
 | 
			
		||||
 | 
			
		||||
  for (size_t i = first + 1; i < last; i++) {
 | 
			
		||||
    task = ddsrt_tasklist_pop(&list, NULL);
 | 
			
		||||
    CU_ASSERT_PTR_EQUAL(task, (TaskHandle_t)i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, 1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, ((DDSRT_TASKLIST_INITIAL*2) - last) - 1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, ((DDSRT_TASKLIST_INITIAL*2) - last) - 1);
 | 
			
		||||
  task = ddsrt_tasklist_pop(&list, NULL);
 | 
			
		||||
  CU_ASSERT_PTR_EQUAL(task, (TaskHandle_t)last);
 | 
			
		||||
  task = ddsrt_tasklist_pop(&list, NULL);
 | 
			
		||||
  CU_ASSERT_PTR_NULL(task);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, 0);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_TheoryDataPoints(ddsrt_sync, tasklist_pop_n_push) = {
 | 
			
		||||
  CU_DataPoints(fill_t,
 | 
			
		||||
    &fill, &fill, &fill, &fill,
 | 
			
		||||
    &fill_wrapped, &fill_wrapped, &fill_wrapped, &fill_wrapped, &fill_wrapped),
 | 
			
		||||
  CU_DataPoints(TaskHandle_t, /* Task to pop. */
 | 
			
		||||
    (TaskHandle_t)NULL,
 | 
			
		||||
    (TaskHandle_t)1,
 | 
			
		||||
    (TaskHandle_t)DDSRT_TASKLIST_CHUNK,
 | 
			
		||||
    (TaskHandle_t)DDSRT_TASKLIST_INITIAL,
 | 
			
		||||
    (TaskHandle_t)NULL,
 | 
			
		||||
    (TaskHandle_t)(DDSRT_TASKLIST_CHUNK + 1),
 | 
			
		||||
    (TaskHandle_t)DDSRT_TASKLIST_INITIAL,
 | 
			
		||||
    (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + 1),
 | 
			
		||||
    (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK)),
 | 
			
		||||
  CU_DataPoints(size_t, /* Expected position to clear. */
 | 
			
		||||
    0, 0, DDSRT_TASKLIST_CHUNK - 1, DDSRT_TASKLIST_INITIAL - 1,
 | 
			
		||||
    DDSRT_TASKLIST_CHUNK, DDSRT_TASKLIST_CHUNK, DDSRT_TASKLIST_INITIAL - 1, 0, DDSRT_TASKLIST_CHUNK - 1),
 | 
			
		||||
  CU_DataPoints(size_t, /* Expected position of pushed task. */
 | 
			
		||||
    0, 0, DDSRT_TASKLIST_INITIAL - 1, DDSRT_TASKLIST_INITIAL - 1,
 | 
			
		||||
    DDSRT_TASKLIST_CHUNK, DDSRT_TASKLIST_CHUNK, DDSRT_TASKLIST_CHUNK, DDSRT_TASKLIST_CHUNK - 1, DDSRT_TASKLIST_CHUNK - 1)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Test to verify tasklist is correctly updated (trimmed and packed) when the
 | 
			
		||||
   tasklist is sparse. */
 | 
			
		||||
CU_Theory((fill_t func, TaskHandle_t task, size_t pos, size_t end), ddsrt_sync, tasklist_pop_n_push)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  func(&list);
 | 
			
		||||
 | 
			
		||||
  if (task == NULL) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, NULL);
 | 
			
		||||
  } else {
 | 
			
		||||
    CU_ASSERT_PTR_EQUAL(ddsrt_tasklist_pop(&list, task), task);
 | 
			
		||||
    CU_ASSERT_PTR_NULL(ddsrt_tasklist_pop(&list, task));
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_PTR_EQUAL(list.tasks[pos], NULL);
 | 
			
		||||
  task = (TaskHandle_t)(DDSRT_TASKLIST_INITIAL*2);
 | 
			
		||||
  CU_ASSERT_NOT_EQUAL_FATAL(ddsrt_tasklist_push(&list, task), -1);
 | 
			
		||||
  CU_ASSERT_PTR_EQUAL(list.tasks[end], task);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_ltrim)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill(&list);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)2);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)3);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - 2);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, 9);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - 3);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 3);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, 9);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_rtrim)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill(&list);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL - 1));
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL - 2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - 2);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - 3);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 4);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_wrapped_ltrim)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill_wrapped(&list);
 | 
			
		||||
 | 
			
		||||
  for (size_t i = DDSRT_TASKLIST_CHUNK+2; i < DDSRT_TASKLIST_INITIAL; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)i);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - (DDSRT_TASKLIST_CHUNK - 2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_CHUNK - 1);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_CHUNK+1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - (DDSRT_TASKLIST_CHUNK - 1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_CHUNK - 1);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL+1));
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, DDSRT_TASKLIST_INITIAL - (DDSRT_TASKLIST_CHUNK + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_CHUNK - 1);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_wrapped_rtrim)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
  size_t last = DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill_wrapped(&list);
 | 
			
		||||
 | 
			
		||||
  for (size_t i = last - 1; i > DDSRT_TASKLIST_INITIAL + 1; i--) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)i);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) + 2);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_CHUNK - 1);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) + 1);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, 0);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL - 1));
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL - 2));
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) - 2);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.cnt, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) - 3);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 4);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_resize)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill(&list);
 | 
			
		||||
 | 
			
		||||
  /* Grow one past initial. Buffer should increase by chunk. */
 | 
			
		||||
  ret = ddsrt_tasklist_push(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(ret, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  /* Grow one past initial+chunk. Buffer should increase by chunk again. */
 | 
			
		||||
  for (size_t i = 2; i <= DDSRT_TASKLIST_CHUNK + 1; i++) {
 | 
			
		||||
    ret = ddsrt_tasklist_push(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + i));
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(ret, 0);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + (DDSRT_TASKLIST_CHUNK*2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
 | 
			
		||||
  /* Shrink one past initial+chunk. Buffer should not decrease by chunk. */
 | 
			
		||||
  for (size_t i = 1; i <= DDSRT_TASKLIST_CHUNK; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)i);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + (DDSRT_TASKLIST_CHUNK*2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
 | 
			
		||||
  /* Shrink to initial. Buffer should decrease by chunk. */
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_CHUNK + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
 | 
			
		||||
  /* Shrink to initial-chunk. Buffer should decrease by chunk. */
 | 
			
		||||
  for (size_t i = DDSRT_TASKLIST_CHUNK+1; i <= (DDSRT_TASKLIST_CHUNK*2)+1; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)i);
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(ret, 0);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) - 1);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_sync, tasklist_wrapped_resize)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_tasklist_t list;
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_init(&list);
 | 
			
		||||
  fill_wrapped(&list);
 | 
			
		||||
 | 
			
		||||
  /* Grow one past initial. Buffer should increase by chunk. */
 | 
			
		||||
  ret = ddsrt_tasklist_push(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(ret, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  /* Grow one past initial+chunk. Buffer should increase by chunk again. */
 | 
			
		||||
  for (size_t i = 2; i <= (DDSRT_TASKLIST_CHUNK + 1); i++) {
 | 
			
		||||
    ret = ddsrt_tasklist_push(&list, (TaskHandle_t)(DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK + i));
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(ret, 0);
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + (DDSRT_TASKLIST_CHUNK*2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
 | 
			
		||||
  /* Shrink one past initial+chunk. Buffer should not decrease by chunk. */
 | 
			
		||||
  for (size_t i = 1; i <= DDSRT_TASKLIST_CHUNK; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)(DDSRT_TASKLIST_CHUNK + i));
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + (DDSRT_TASKLIST_CHUNK*2));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
 | 
			
		||||
  /* Shrink to initial. Buffer should decrease by chunk. */
 | 
			
		||||
  ddsrt_tasklist_pop(&list, (TaskHandle_t)((DDSRT_TASKLIST_CHUNK*2) + 1));
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL + DDSRT_TASKLIST_CHUNK);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, DDSRT_TASKLIST_INITIAL - 1);
 | 
			
		||||
 | 
			
		||||
  /* Shrink to initial-chunk. Buffer should decrease by chunk. */
 | 
			
		||||
  for (size_t i = 2; i <= DDSRT_TASKLIST_CHUNK + 1; i++) {
 | 
			
		||||
    ddsrt_tasklist_pop(&list, (TaskHandle_t)((DDSRT_TASKLIST_CHUNK*2) + i));
 | 
			
		||||
  }
 | 
			
		||||
  CU_ASSERT_EQUAL(list.len, DDSRT_TASKLIST_INITIAL);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.off, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(list.end, (DDSRT_TASKLIST_INITIAL - DDSRT_TASKLIST_CHUNK) - 1);
 | 
			
		||||
 | 
			
		||||
  ddsrt_tasklist_fini(&list);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,9 +11,12 @@
 | 
			
		|||
 */
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#if !defined(_WIN32)
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
# include <FreeRTOS.h>
 | 
			
		||||
# include <task.h>
 | 
			
		||||
#elif !defined(_WIN32)
 | 
			
		||||
# include <sched.h>
 | 
			
		||||
# include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "CUnit/Theory.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +33,10 @@ static int32_t min_other_prio = 250;
 | 
			
		|||
CU_Init(ddsrt_thread)
 | 
			
		||||
{
 | 
			
		||||
  ddsrt_init();
 | 
			
		||||
#if defined(WIN32)
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
  max_other_prio = max_fifo_prio = configMAX_PRIORITIES - 1;
 | 
			
		||||
  min_other_prio = min_fifo_prio = tskIDLE_PRIORITY + 1;
 | 
			
		||||
#elif defined(WIN32)
 | 
			
		||||
  max_fifo_prio = THREAD_PRIORITY_HIGHEST;
 | 
			
		||||
  min_fifo_prio = THREAD_PRIORITY_LOWEST;
 | 
			
		||||
  max_other_prio = THREAD_PRIORITY_HIGHEST;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +65,7 @@ typedef struct {
 | 
			
		|||
  ddsrt_threadattr_t *attr;
 | 
			
		||||
} thread_arg_t;
 | 
			
		||||
 | 
			
		||||
uint32_t thread_main(void *ptr)
 | 
			
		||||
static uint32_t thread_main(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
  thread_arg_t *arg = (thread_arg_t *)ptr;
 | 
			
		||||
  ddsrt_threadattr_t *attr;
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +74,12 @@ uint32_t thread_main(void *ptr)
 | 
			
		|||
 | 
			
		||||
  attr = arg->attr;
 | 
			
		||||
 | 
			
		||||
#if _WIN32
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
  int prio = (int)uxTaskPriorityGet(NULL);
 | 
			
		||||
  if (prio == attr->schedPriority) {
 | 
			
		||||
    arg->res = 1;
 | 
			
		||||
  }
 | 
			
		||||
#elif _WIN32
 | 
			
		||||
  int prio = GetThreadPriority(GetCurrentThread());
 | 
			
		||||
  if (prio == THREAD_PRIORITY_ERROR_RETURN)
 | 
			
		||||
    abort();
 | 
			
		||||
| 
						 | 
				
			
			@ -108,12 +119,17 @@ CU_Theory((ddsrt_sched_t sched, int32_t *prio, uint32_t exp), ddsrt_thread, crea
 | 
			
		|||
{
 | 
			
		||||
  int skip = 0;
 | 
			
		||||
  uint32_t res = 50505;
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  thread_arg_t arg;
 | 
			
		||||
 | 
			
		||||
#if defined(__VXWORKS__)
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
  if (sched == DDSRT_SCHED_TIMESHARE) {
 | 
			
		||||
    skip = 1;
 | 
			
		||||
    CU_PASS("FreeRTOS only support SCHED_FIFO");
 | 
			
		||||
  }
 | 
			
		||||
#elif defined(__VXWORKS__)
 | 
			
		||||
# if defined(_WRS_KERNEL)
 | 
			
		||||
  if (sched == DDSRT_SCHED_TIMESHARE) {
 | 
			
		||||
    skip = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -150,7 +166,9 @@ CU_Test(ddsrt_thread, thread_id)
 | 
			
		|||
{
 | 
			
		||||
  int eq = 0;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
  TaskHandle_t task;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
  DWORD _tid;
 | 
			
		||||
#else
 | 
			
		||||
  pthread_t _thr;
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +176,10 @@ CU_Test(ddsrt_thread, thread_id)
 | 
			
		|||
 | 
			
		||||
  thr = ddsrt_thread_self();
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#if DDSRT_WITH_FREERTOS
 | 
			
		||||
  task = xTaskGetCurrentTaskHandle();
 | 
			
		||||
  eq = (thr.task == task);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
  _tid = GetCurrentThreadId();
 | 
			
		||||
  eq = (thr.tid == _tid);
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +193,7 @@ CU_Test(ddsrt_thread, thread_id)
 | 
			
		|||
 | 
			
		||||
static ddsrt_mutex_t locks[2];
 | 
			
		||||
 | 
			
		||||
uint32_t thread_main_waitforme(void *ptr)
 | 
			
		||||
static uint32_t thread_main_waitforme(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t ret = 0;
 | 
			
		||||
  (void)ptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +203,7 @@ uint32_t thread_main_waitforme(void *ptr)
 | 
			
		|||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t thread_main_waitforit(void *ptr)
 | 
			
		||||
static uint32_t thread_main_waitforit(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t res = 0;
 | 
			
		||||
  ddsrt_thread_t *thr = (ddsrt_thread_t *)ptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +215,7 @@ uint32_t thread_main_waitforit(void *ptr)
 | 
			
		|||
 | 
			
		||||
CU_Test(ddsrt_thread, stacked_join)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t ret;
 | 
			
		||||
  dds_return_t ret;
 | 
			
		||||
  ddsrt_thread_t thrs[2];
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
  uint32_t res = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -230,4 +251,3 @@ CU_Test(ddsrt_thread, attribute)
 | 
			
		|||
  CU_ASSERT_EQUAL(attr.schedPriority, 0);
 | 
			
		||||
  CU_ASSERT_EQUAL(attr.stackSize, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ static void
 | 
			
		|||
setup(
 | 
			
		||||
  struct thread_argument *arg)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t rc;
 | 
			
		||||
  dds_return_t rc;
 | 
			
		||||
  ddsrt_thread_t thr;
 | 
			
		||||
  ddsrt_threadattr_t attr;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue