static struct {
int sockfd;
- switch_mutex_t *mutex;
switch_mutex_t *sock_mutex;
listener_t *listeners;
uint8_t ready;
static void launch_listener_thread(listener_t *listener);
static struct {
+ switch_mutex_t *listener_mutex;
switch_event_node_t *node;
} globals;
{
listener_t *l;
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
for (l = listen_list.listeners; l; l = l->next) {
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
char *data = strdup(node->data);
}
}
}
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
return SWITCH_STATUS_SUCCESS;
}
lp = listen_list.listeners;
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
while(lp) {
uint8_t send = 0;
}
}
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
+}
+
+
+static void close_socket(int *sock)
+{
+ switch_mutex_lock(listen_list.sock_mutex);
+ if (*sock) {
+ shutdown(*sock, SHUT_RDWR);
+ close(*sock);
+ sock = NULL;
+ }
+ switch_mutex_unlock(listen_list.sock_mutex);
}
switch_log_unbind_logger(socket_logger);
- close(listen_list.sockfd);
+ /*close_socket(&listen_list.sockfd);*/
- switch_yield(500);
-
- while (prefs.threads) {
+ while (prefs.threads || prefs.done == 1) {
switch_yield(10000);
if (++sanity == 1000) {
break;
}
}
+
switch_event_unbind(&globals.node);
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
+
for (l = listen_list.listeners; l; l = l->next) {
- close(l->sockfd);
+ close_socket(&l->sockfd);
}
- switch_mutex_unlock(listen_list.mutex);
+
+ switch_mutex_unlock(globals.listener_mutex);
return SWITCH_STATUS_SUCCESS;
}
static void add_listener(listener_t *listener)
{
/* add me to the listeners so I get events */
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
listener->next = listen_list.listeners;
listen_list.listeners = listener;
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
}
{
listener_t *l, *last = NULL;
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
for (l = listen_list.listeners; l; l = l->next) {
if (l == listener) {
if (last) {
}
last = l;
}
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
}
SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load)
{
+ switch_mutex_init(&globals.listener_mutex, SWITCH_MUTEX_NESTED, pool);
+
+ if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+ close_socket(&listen_list.sockfd);
+ return SWITCH_STATUS_GENERR;
+ }
+
+ switch_log_bind_logger(socket_logger, SWITCH_LOG_DEBUG, SWITCH_FALSE);
+
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
int status = 1;
void *pop;
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
prefs.threads++;
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
switch_assert(listener != NULL);
switch_thread_rwlock_wrlock(listener->rwlock);
if (listener->sockfd) {
- close(listener->sockfd);
+ close_socket(&listener->sockfd);
}
switch_thread_rwlock_unlock(listener->rwlock);
switch_core_destroy_memory_pool(&pool);
}
- switch_mutex_lock(listen_list.mutex);
+ switch_mutex_lock(globals.listener_mutex);
prefs.threads--;
- switch_mutex_unlock(listen_list.mutex);
+ switch_mutex_unlock(globals.listener_mutex);
return NULL;
}
struct sockaddr_in server_addr;
int on = 1;
int clientfd;
+ int epmdfd;
memset(&listen_list, 0, sizeof(listen_list));
config();
return SWITCH_STATUS_TERM;
}
- switch_mutex_init(&listen_list.mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_init(&listen_list.sock_mutex, SWITCH_MUTEX_NESTED, pool);
/* zero out the struct before we use it */
goto sock_fail;
}
- if (setsockopt(listen_list.sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
+ if (setsockopt(listen_list.sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to enable SO_REUSEADDR for socket on %s:%u : %s\n", prefs.ip, prefs.port, strerror(errno));
goto sock_fail;
}
/* init the ei stuff */
if (ei_connect_xinit(&ec, thishostname, prefs.nodename, thisnodename, (Erl_IpAddr)(&server_addr.sin_addr.s_addr), prefs.cookie, 0) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init ei connection\n");
+ close_socket(&listen_list.sockfd);
return SWITCH_STATUS_GENERR;
}
/* return value is -1 for error, a descriptor pointing to epmd otherwise */
- if (ei_publish(&ec, prefs.port) == -1) {
+ if ((epmdfd = ei_publish(&ec, prefs.port)) == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to publish port to empd\n");
+ /* TODO - start epmd? */
+ close_socket(&listen_list.sockfd);
return SWITCH_STATUS_GENERR;
}
listen_list.ready = 1;
- if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
- return SWITCH_STATUS_GENERR;
- }
-
- switch_log_bind_logger(socket_logger, SWITCH_LOG_DEBUG, SWITCH_FALSE);
-
for (;;) {
/* zero out errno because ei_accept doesn't differentiate between a
* failed authentication or a socket failure, or a client version
}
- close(listen_list.sockfd);
+ /* cleanup epmd registration */
+ ei_unpublish(&ec);
+ close(epmdfd);
+
+ close_socket(&listen_list.sockfd);
if (pool) {
switch_core_destroy_memory_pool(&pool);
switch_safe_free(prefs.acl[x]);
}
+ prefs.done = 2;
fail:
return SWITCH_STATUS_TERM;
}