75 "Usage: ex_network_reactor [options]\n"
76 " -a ADDR server mode, bind ADDR (use \"\" for all interfaces)\n"
77 " -s HOST client mode, connect to HOST\n"
78 " -p PORT port (required)\n"
79 " -n COUNT server: connections to handle, client: connect attempts (default 5)\n"
80 " -V LEVEL log level: LOG_DEBUG/LOG_INFO/LOG_NOTICE/LOG_ERR (default LOG_NOTICE)\n"
81 " -h show this help\n");
101 n_log(
LOG_NOTICE,
"reactor server listening on %s:%s (target %d connections)",
109 n_log(
LOG_NOTICE,
"n_reactor unavailable on this platform, skipping (exit 0)");
115 pthread_t reactor_thr;
117 n_log(
LOG_ERR,
"pthread_create(reactor): %s", strerror(errno));
131 pthread_join(reactor_thr, NULL);
198 "reactor stats: events=%lld registered=%lld unregistered=%lld "
199 "wake=%lld writes_partial=%lld reads_partial=%lld",
204 pthread_join(reactor_thr, NULL);
209 n_log(
LOG_NOTICE,
"reactor server done (%d connections handled)", handled);
224 for (
int i = 0;
g_running && i < attempts; i++) {
227 n_log(
LOG_ERR,
"client connect %d/%d to %s:%s failed", i + 1, attempts, host,
port);
234 snprintf(payload,
sizeof(payload),
"hello-from-client-%d", i + 1);
245 n_log(
LOG_ERR,
"client %d: no echo within timeout", i + 1);
254int main(
int argc,
char** argv) {
261 int explicit_server = 0;
264 while ((opt = getopt(argc, argv,
"ha:s:p:n:V:")) != -1) {
269 addr = strdup(optarg);
273 host = strdup(optarg);
276 port = strdup(optarg);
279 count = atoi(optarg);
280 if (count <= 0) count = 1;
283 if (!strcmp(optarg,
"LOG_DEBUG"))
285 else if (!strcmp(optarg,
"LOG_INFO"))
287 else if (!strcmp(optarg,
"LOG_NOTICE"))
289 else if (!strcmp(optarg,
"LOG_ERR"))
301 (void)explicit_server;
304 fprintf(stderr,
"ex_network_reactor: -p PORT is required\n");
315 signal(SIGPIPE, SIG_IGN);
static void sighandler(int sig)
static void run_server(char *port, double fake_offset, int nb_rounds)
static void run_client(char *server, char *port, int nb_rounds)
NETWORK * netw
Network for server mode, accepting incomming.
static volatile sig_atomic_t g_running
#define FreeNoLog(__ptr)
Free Handler without log.
void * ptr
void pointer to store
LIST_NODE * start
pointer to the start of the list
size_t nb_items
number of item currently in the list
struct LIST_NODE * next
pointer to the next node
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
int list_destroy(LIST **list)
Empty and Free a list container.
void * remove_list_node_f(LIST *list, LIST_NODE *node)
Internal function called each time we need to get a node out of a list.
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
Structure of a generic LIST container.
Structure of a generic list node.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
#define LOG_NOTICE
normal but significant condition
#define LOG_INFO
informational
size_t length
total allocation (in bytes) of the data buffer, padding included
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
A box including a string and his lenght.
void u_sleep(unsigned int usec)
wrapper around usleep for API consistency
N_SOCKET link
networking socket
SOCKET sock
a normal socket
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
N_STR * netw_wait_msg(NETWORK *netw, unsigned int refresh, size_t timeout)
Wait a message from aimed NETWORK.
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
Common headers and low-level functions & define.
void * n_reactor_run_thread_entry(void *arg)
pthread_create-compatible entry point that calls n_reactor_run on the reactor passed via arg.
void n_reactor_get_stats(const n_reactor *reactor, n_reactor_stats *out)
Read current stats counters into *out.
n_reactor * n_reactor_new(int max_fds_hint)
Create a new reactor.
NETWORK * netw_accept_into_reactor(NETWORK *listener, size_t send_list_limit, size_t recv_list_limit, int blocking, n_reactor *reactor, int *retval)
Accept a connection on listener and register it with reactor instead of starting per-connection threa...
void n_reactor_stop(n_reactor *reactor)
Signal the run loop to exit at the next iteration.
void n_reactor_destroy(n_reactor **reactor)
Tear down a reactor.
Single-threaded epoll reactor for n_network connections.
long long fds_registered
lifetime register call count
long long writes_partial
EAGAIN on send -> re-armed EPOLLOUT.
long long reads_partial
EAGAIN on recv -> kept accumulator.
long long events_processed
total epoll events dispatched
long long wake_signals
eventfd wake events processed
struct n_reactor n_reactor
Opaque reactor handle.
long long fds_unregistered
lifetime unregister call count
Counters for the dashboard / profile_server.sh.