Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Static Linking #1261

Merged
merged 9 commits into from
Jan 23, 2022
2 changes: 2 additions & 0 deletions aeron-client/src/main/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ set(SOURCE
util/aeron_parse_util.c
util/aeron_properties_util.c
util/aeron_strutil.c
util/aeron_symbol_table.c
uri/aeron_uri.c
aeron_agent.c
aeron_alloc.c
Expand Down Expand Up @@ -152,6 +153,7 @@ set(HEADERS
util/aeron_platform.h
util/aeron_properties_util.h
util/aeron_strutil.h
util/aeron_symbol_table.h
uri/aeron_uri.h
aeron_agent.h
aeron_alloc.h
Expand Down
79 changes: 31 additions & 48 deletions aeron-client/src/main/c/aeron_agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "util/aeron_error.h"
#include "util/aeron_dlopen.h"
#include "util/aeron_parse_util.h"
#include "util/aeron_symbol_table.h"
#include "aeron_agent.h"
#include "aeron_alloc.h"

Expand Down Expand Up @@ -282,6 +283,19 @@ aeron_idle_strategy_t aeron_idle_strategy_backoff =
aeron_idle_strategy_backoff_state_init_args
};

static const aeron_symbol_table_obj_t aeron_idle_strategy_table[] =
{
{ "sleeping", "aeron_idle_strategy_sleeping", &aeron_idle_strategy_sleeping },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name should be sleep rather than sleeping to have consistent naming.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but I'd like to make that a separate change to this PR. The current PR preserves behaviour: https://github.com/real-logic/aeron/blob/master/aeron-client/src/main/c/aeron_agent.c#L301. I think it also requires a "sleep-ms" to be consistent with the Java driver as well.

{ "sleep-ns", "aeron_idle_strategy_sleeping", &aeron_idle_strategy_sleeping },
{ "yield", "aeron_idle_strategy_yielding", &aeron_idle_strategy_yielding },
{ "spin", "aeron_idle_strategy_busy_spinning", &aeron_idle_strategy_busy_spinning },
{ "noop", "aeron_idle_strategy_noop", &aeron_idle_strategy_noop },
{ "backoff", "aeron_idle_strategy_backoff", &aeron_idle_strategy_backoff },
};

static const size_t aeron_idle_strategy_table_length =
sizeof(aeron_idle_strategy_table) / sizeof (aeron_symbol_table_obj_t);

aeron_idle_strategy_func_t aeron_idle_strategy_load(
const char *idle_strategy_name,
void **idle_strategy_state,
Expand All @@ -292,74 +306,43 @@ aeron_idle_strategy_func_t aeron_idle_strategy_load(

if (NULL == idle_strategy_name || NULL == idle_strategy_state)
{
AERON_SET_ERR(EINVAL, "%s", "invalid idle strategy name or state");
AERON_SET_ERR(EINVAL, "%s", "invalid idle object name or state");
return NULL;
}

*idle_strategy_state = NULL;
aeron_idle_strategy_t *idle_strategy = aeron_symbol_table_obj_load(
aeron_idle_strategy_table, aeron_idle_strategy_table_length, idle_strategy_name, "idle strategy");

if (strncmp(idle_strategy_name, "sleep-ns", strlen("sleep-ns")) == 0 ||
strncmp(idle_strategy_name, "sleeping", strlen("sleeping")) == 0)
{
return aeron_idle_strategy_load("aeron_idle_strategy_sleeping", idle_strategy_state, env_var, init_args);
}
else if (strncmp(idle_strategy_name, "yield", strlen("yield")) == 0)
if (NULL == idle_strategy)
{
return aeron_idle_strategy_load("aeron_idle_strategy_yielding", idle_strategy_state, env_var, init_args);
}
else if (strncmp(idle_strategy_name, "spin", strlen("spin")) == 0)
{
return aeron_idle_strategy_load("aeron_idle_strategy_busy_spinning", idle_strategy_state, env_var, init_args);
}
else if (strncmp(idle_strategy_name, "noop", strlen("noop")) == 0)
{
return aeron_idle_strategy_load("aeron_idle_strategy_noop", idle_strategy_state, env_var, init_args);
}
else if (strncmp(idle_strategy_name, "backoff", strlen("backoff")) == 0)
{
return aeron_idle_strategy_load("aeron_idle_strategy_backoff", idle_strategy_state, env_var, init_args);
AERON_APPEND_ERR("%s", "");
return NULL;
}
else
{
char idle_func_name[AERON_MAX_PATH] = { 0 };
aeron_idle_strategy_t *idle_strategy = NULL;

snprintf(idle_func_name, sizeof(idle_func_name) - 1, "%s", idle_strategy_name);
if ((idle_strategy = (aeron_idle_strategy_t *)aeron_dlsym(RTLD_DEFAULT, idle_func_name)) == NULL)
{
AERON_SET_ERR(EINVAL, "could not find idle strategy %s: dlsym - %s", idle_func_name, aeron_dlerror());
return NULL;
}
idle_func = idle_strategy->idle;
aeron_idle_strategy_init_func_t idle_init_func = idle_strategy->init;

void *idle_state = NULL;
if (idle_init_func(&idle_state, env_var, init_args) < 0)
{
return NULL;
}
*idle_strategy_state = NULL;
idle_func = idle_strategy->idle;
aeron_idle_strategy_init_func_t idle_init_func = idle_strategy->init;

*idle_strategy_state = idle_state;
void *idle_state = NULL;
if (idle_init_func(&idle_state, env_var, init_args) < 0)
{
return NULL;
}

*idle_strategy_state = idle_state;

return idle_func;
}

aeron_agent_on_start_func_t aeron_agent_on_start_load(const char *name)
{
aeron_agent_on_start_func_t func = NULL;
#if defined(AERON_COMPILER_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
if ((func = (aeron_agent_on_start_func_t)aeron_dlsym(RTLD_DEFAULT, name)) == NULL)

if ((*(void **)(&func) = aeron_dlsym(RTLD_DEFAULT, name)) == NULL)
{
AERON_SET_ERR(EINVAL, "could not find agent on_start func %s: dlsym - %s", name, aeron_dlerror());
return NULL;
}
#if defined(AERON_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif

return func;
}
Expand Down
2 changes: 2 additions & 0 deletions aeron-client/src/main/c/aeron_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ uint8_t aeron_semantic_version_minor(int32_t version);

uint8_t aeron_semantic_version_patch(int32_t version);

typedef void (*aeron_fptr_t)(void);

#endif //AERON_COMMON_H
19 changes: 19 additions & 0 deletions aeron-client/src/main/c/util/aeron_dlopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ const char *aeron_dlinfo(const void *addr, char *buffer, size_t max_buffer_lengt
return buffer;
}

const char *aeron_dlinfo_func(void (*func)(void), char *buffer, size_t max_buffer_length)
{
#if defined(AERON_COMPILER_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
void *addr = (void *)func;
#if defined(AERON_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
return aeron_dlinfo(addr, buffer, max_buffer_length);
}

#elif defined(AERON_COMPILER_MSVC)

#include "concurrent/aeron_counters_manager.h"
Expand Down Expand Up @@ -158,6 +171,12 @@ char *aeron_dlerror()
return messageBuffer;
}

const char *aeron_dlinfo_func(void (*func)(void), char *buffer, size_t max_buffer_length)
{
buffer[0] = '\0';
return buffer;
}

const char *aeron_dlinfo(const void *addr, char *buffer, size_t max_buffer_length)
{
buffer[0] = '\0';
Expand Down
4 changes: 3 additions & 1 deletion aeron-client/src/main/c/util/aeron_dlopen.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
#define aeron_dlopen(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL)
#define aeron_dlerror dlerror

const char *aeron_dlinfo(const void *addr, char *buffer, size_t max_buffer_length);
const char *aeron_dlinfo(const void *, char *buffer, size_t max_buffer_length);
const char *aeron_dlinfo_func(void (*func)(void), char *buffer, size_t max_buffer_length);

#elif defined(AERON_COMPILER_MSVC)

Expand All @@ -39,6 +40,7 @@ void *aeron_dlsym(void *module, const char *name);
void *aeron_dlopen(const char *filename);
char *aeron_dlerror();
const char *aeron_dlinfo(const void *addr, char *buffer, size_t max_buffer_length);
const char *aeron_dlinfo_func(void (*func)(void), char *buffer, size_t max_buffer_length);

#else
#error Unsupported platform!
Expand Down
1 change: 1 addition & 0 deletions aeron-client/src/main/c/util/aeron_strutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,3 +263,4 @@ int getopt(int argc, char *const argv[], const char *opt_string)
#endif

extern uint64_t aeron_fnv_64a_buf(uint8_t *buf, size_t len);
extern bool aeron_str_length(const char *str, size_t length_bound, size_t *length);
37 changes: 37 additions & 0 deletions aeron-client/src/main/c/util/aeron_strutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

void aeron_format_date(char *str, size_t count, int64_t timestamp);

Expand Down Expand Up @@ -78,4 +79,40 @@ AERON_EXPORT extern int optind;
int getopt(int argc, char *const argv[], const char *opt_string);
#endif

/**
* Checks that the string length is strictly less than the specified bound.
*
* @param str String to be compared.
* @param length_bound Limit to the length of the string being checked.
* @param length Out parameter for the actual length of the string (if non-null and less than length_bound).
* NULL values for this parameter are permitted. If str is NULL this value is unmodified. If
* the function returns false, the value is also unmodified.
* @return true if less than the specified bound, NULL is always true.
*/
inline bool aeron_str_length(const char *str, size_t length_bound, size_t *length)
{
if (NULL == str)
{
return true;
}

size_t i = 0;
bool result = false;
for (; i < length_bound; i++)
{
if ('\0' == str[i])
{
result = true;
break;
}
}

if (result && NULL != length)
{
*length = i;
}

return result;
}

#endif //AERON_STRUTIL_H
Loading