static void nn_global_init (void) { int i; #if defined NN_HAVE_WINDOWS WSADATA data; int rc; #endif /* Check whether the library was already initialised. If so, do nothing. */ if (self.socks) return; /* On Windows, initialise the socket library. */ #if defined NN_HAVE_WINDOWS rc = WSAStartup (MAKEWORD (2, 2), &data); nn_assert (rc == 0); nn_assert (LOBYTE (data.wVersion) == 2 && HIBYTE (data.wVersion) == 2); #endif /* Initialise the memory allocation subsystem. */ nn_alloc_init (); /* Seed the pseudo-random number generator. */ nn_random_seed (); /* Allocate the global table of SP sockets. */ self.socks = nn_alloc ((sizeof (struct nn_sock*) * NN_MAX_SOCKETS) + (sizeof (uint16_t) * NN_MAX_SOCKETS), "socket table"); alloc_assert (self.socks); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.socks [i] = NULL; self.nsocks = 0; self.flags = 0; /* Allocate the stack of unused file descriptors. */ self.unused = (uint16_t*) (self.socks + NN_MAX_SOCKETS); alloc_assert (self.unused); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.unused [i] = NN_MAX_SOCKETS - i - 1; /* Initialise other parts of the global state. */ nn_list_init (&self.transports); nn_list_init (&self.socktypes); /* Plug in individual transports. */ nn_global_add_transport (nn_inproc); #if !defined NN_HAVE_WINDOWS nn_global_add_transport (nn_ipc); #endif nn_global_add_transport (nn_tcp); /* Plug in individual socktypes. */ nn_global_add_socktype (nn_pair_socktype); nn_global_add_socktype (nn_xpair_socktype); nn_global_add_socktype (nn_pub_socktype); nn_global_add_socktype (nn_sub_socktype); nn_global_add_socktype (nn_rep_socktype); nn_global_add_socktype (nn_req_socktype); nn_global_add_socktype (nn_xrep_socktype); nn_global_add_socktype (nn_xreq_socktype); nn_global_add_socktype (nn_push_socktype); nn_global_add_socktype (nn_xpush_socktype); nn_global_add_socktype (nn_pull_socktype); nn_global_add_socktype (nn_xpull_socktype); nn_global_add_socktype (nn_respondent_socktype); nn_global_add_socktype (nn_surveyor_socktype); nn_global_add_socktype (nn_xrespondent_socktype); nn_global_add_socktype (nn_xsurveyor_socktype); nn_global_add_socktype (nn_bus_socktype); nn_global_add_socktype (nn_xbus_socktype); /* Start the worker threads. */ nn_pool_init (&self.pool); }
static void nn_global_init (void) { int i; char *envvar; int rc; char *addr; #if defined NN_HAVE_WINDOWS WSADATA data; #endif /* Check whether the library was already initialised. If so, do nothing. */ if (self.socks) return; /* On Windows, initialise the socket library. */ #if defined NN_HAVE_WINDOWS rc = WSAStartup (MAKEWORD (2, 2), &data); nn_assert (rc == 0); nn_assert (LOBYTE (data.wVersion) == 2 && HIBYTE (data.wVersion) == 2); #endif /* Initialise the memory allocation subsystem. */ nn_alloc_init (); /* Seed the pseudo-random number generator. */ nn_random_seed (); /* Allocate the global table of SP sockets. */ self.socks = nn_alloc ((sizeof (struct nn_sock*) * NN_MAX_SOCKETS) + (sizeof (uint16_t) * NN_MAX_SOCKETS), "socket table"); alloc_assert (self.socks); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.socks [i] = NULL; self.nsocks = 0; self.flags = 0; /* Print connection and accepting errors to the stderr */ envvar = getenv("NN_PRINT_ERRORS"); /* any non-empty string is true */ self.print_errors = envvar && *envvar; /* Print socket statistics to stderr */ envvar = getenv("NN_PRINT_STATISTICS"); self.print_statistics = envvar && *envvar; /* Allocate the stack of unused file descriptors. */ self.unused = (uint16_t*) (self.socks + NN_MAX_SOCKETS); alloc_assert (self.unused); for (i = 0; i != NN_MAX_SOCKETS; ++i) self.unused [i] = NN_MAX_SOCKETS - i - 1; /* Initialise other parts of the global state. */ nn_list_init (&self.transports); nn_list_init (&self.socktypes); /* Plug in individual transports. */ nn_global_add_transport (nn_inproc); nn_global_add_transport (nn_ipc); nn_global_add_transport (nn_tcp); nn_global_add_transport (nn_ws); nn_global_add_transport (nn_tcpmux); /* Plug in individual socktypes. */ nn_global_add_socktype (nn_pair_socktype); nn_global_add_socktype (nn_xpair_socktype); nn_global_add_socktype (nn_pub_socktype); nn_global_add_socktype (nn_sub_socktype); nn_global_add_socktype (nn_xpub_socktype); nn_global_add_socktype (nn_xsub_socktype); nn_global_add_socktype (nn_rep_socktype); nn_global_add_socktype (nn_req_socktype); nn_global_add_socktype (nn_xrep_socktype); nn_global_add_socktype (nn_xreq_socktype); nn_global_add_socktype (nn_push_socktype); nn_global_add_socktype (nn_xpush_socktype); nn_global_add_socktype (nn_pull_socktype); nn_global_add_socktype (nn_xpull_socktype); nn_global_add_socktype (nn_respondent_socktype); nn_global_add_socktype (nn_surveyor_socktype); nn_global_add_socktype (nn_xrespondent_socktype); nn_global_add_socktype (nn_xsurveyor_socktype); nn_global_add_socktype (nn_bus_socktype); nn_global_add_socktype (nn_xbus_socktype); /* Start the worker threads. */ nn_pool_init (&self.pool); /* Start FSM */ nn_fsm_init_root (&self.fsm, nn_global_handler, nn_global_shutdown, &self.ctx); self.state = NN_GLOBAL_STATE_IDLE; nn_ctx_init (&self.ctx, nn_global_getpool (), NULL); nn_timer_init (&self.stat_timer, NN_GLOBAL_SRC_STAT_TIMER, &self.fsm); nn_fsm_start (&self.fsm); /* Initializing special sockets. */ addr = getenv ("NN_STATISTICS_SOCKET"); if (addr) { self.statistics_socket = nn_global_create_socket (AF_SP, NN_PUB); errno_assert (self.statistics_socket >= 0); rc = nn_global_create_ep (self.statistics_socket, addr, 0); errno_assert (rc >= 0); } else { self.statistics_socket = -1; } addr = getenv ("NN_APPLICATION_NAME"); if (addr) { strncpy (self.appname, addr, 63); self.appname[63] = '\0'; } else { /* No cross-platform way to find out application binary. Also, MSVC suggests using _getpid() instead of getpid(), however, it's not clear whether the former is supported by older versions of Windows/MSVC. */ #if defined _MSC_VER #pragma warning (push) #pragma warning (disable:4996) #endif sprintf (self.appname, "nanomsg.%d", getpid()); #if defined _MSC_VER #pragma warning (pop) #endif } addr = getenv ("NN_HOSTNAME"); if (addr) { strncpy (self.hostname, addr, 63); self.hostname[63] = '\0'; } else { rc = gethostname (self.hostname, 63); errno_assert (rc == 0); self.hostname[63] = '\0'; } }