Example #1
0
/*
 * Initializes all listening servers and their structures,
 * if the data is already initialized 0 is returned and the call
 * has no effect
 */
int SIOInit(int stdoutPort, int stderrPort) {
    int last_error;
    /* check for status  */
    if (sio_servers_initialized == 1) {
        return 0;
    }
    /* check port numbers  */
    if (stdoutPort < 0 && stderrPort < 0) {
        return 0;
    } else {
        /* provider should start
        must start both sockets
        so make sure values are correct */
        if (stdoutPort < 0) {
            stdoutPort = 0;
        }
        if (stderrPort < 0) {
            stderrPort = 0;
        }
    }
    /* start WSA */
    sio_debug("Starting WSA");
    last_error = sio_init_WSA();
    if (last_error != 0) {
        return last_error;
    }
    /* init servers  */
    sio_debug("Initializinig servers with ports %d and %d", stdoutPort, stderrPort);
    last_error = sio_init_server(&sio_stdout_server, stdoutPort);
    if (last_error != 0) {
        return last_error;
    }
    last_error = sio_init_server(&sio_stderr_server, stderrPort);
    if (last_error != 0) {
        return last_error;
    }
    /* start servers  */
    sio_debug("Starting servers");
    last_error = sio_start_server(&sio_stdout_server);
    if (last_error != 0) {
        return last_error;
    }
    last_error = sio_start_server(&sio_stderr_server);
    if (last_error != 0) {
        return last_error;
    }
    sio_servers_initialized = 1;
    return 0;
}
Example #2
0
/* 
 *  Acquires the Mutex for current thread
 */
static void sio_lock_clients(SIO_SERVER * server) {
    DWORD wait_result;
    int last_error;
    wait_result = WaitForSingleObject(server->clients.mutex, INFINITE);
    while (wait_result != WAIT_OBJECT_0) {
        if (wait_result == WAIT_FAILED) {
            sio_handle_system_error("Canot obtain mutex lock");
            return;
        } else {
            sio_debug("Failed to obtain lock with result %d. Trying again", wait_result);
        }
        wait_result = WaitForSingleObject(server->clients.mutex, INFINITE);
    }
    sio_debug("LOCK");
}
Example #3
0
/* 
 *  Sends supplied data to all connected clients
 *  This function acquires its own lock
 */
static int sio_send_data_to_clients(SIO_SERVER * server, char * data, int len) {
    int cli_iter, add_iter;
    int * log;
    /* prepare log */
    sio_lock_clients(server);
    log = (int *) malloc(server->clients.count * sizeof(int));
    /* send data to clients */
    for ( cli_iter = 0; cli_iter < server->clients.count; cli_iter++ ) {
        if (send(server->clients.list[cli_iter], data, len, 0) == SOCKET_ERROR) {
            log[cli_iter] = sio_handle_WSA_error("Canot send data to client, closing");
        } else {
            log[cli_iter] = 0;
        }
    }
    /* remove disfunctional sockets */
    add_iter = 0;
    for ( cli_iter = 0; cli_iter < server->clients.count; cli_iter++ ) {
        if (log[cli_iter] == 0) {
            server->clients.list[add_iter] = server->clients.list[cli_iter];
            add_iter++;
        }
    }
    free(log);
    server->clients.count = add_iter;
    sio_debug("Sent %d bytes to %d clients", len, server->clients.count);
    sio_unlock_clients(server);
    return 0;
}
Example #4
0
/* 
 *  Initializes the WSA Provider
 */
static int sio_init_WSA() {
    int error_code;
    error_code = WSAStartup(WINSOCK_VERSION, &sio_WSA_data);
    if (error_code != 0) {
        sio_debug("WSAStartup() failed with error code = %d", error_code);
        return error_code;
    } else {
        return 0;
    }
}
Example #5
0
/* 
 *  Reads port information from socket
 */
int sio_get_server_port(SIO_SERVER * server) {
    struct sockaddr_in address;
    int len = sizeof(address);
    if (getsockname(server->socket, (SOCKADDR*) &address, &len) == SOCKET_ERROR) {
        return sio_handle_WSA_error("Canot retrieve server address");
    } else {
        server->port = ntohs(address.sin_port);
        sio_debug("Server started on port %d", server->port);
        return 0;
    }
}
Example #6
0
/* 
 *  Adds a client to active clients registry
 *  Performs registry expansion if necessary
 *  Current thread must hold the registry Mutex in order to guarantee
 *  thread-security
 */
static void sio_add_client(SIO_SERVER * server, SOCKET client) {
    SOCKET * old_clients = NULL;
    int i = 0;
    /* expand if necessary */
    if (server->clients.count == server->clients.length) {
        sio_debug("Expanding clients array");
        old_clients = server->clients.list;
        server->clients.length += SIO_CLIENTS_DELTA;
        server->clients.list =
	    (SOCKET *) malloc(server->clients.length * sizeof(SOCKET));
        for (i = 0; i < server->clients.count; i++) {
            server->clients.list[i] = old_clients[i];
        }
        free(old_clients);
        sio_debug("Done");
    }
    /* add a client */
    server->clients.list[server->clients.count] = client;
    server->clients.count++;
    sio_debug("Client added");
}
Example #7
0
/* 
 *  Prints a debug error message for given error code with given
 *  descrioption and error type
 */
static int sio_handle_error(char * type, char * msg, int error_code) {
#ifdef SIO_DEBUG
    LPVOID message_buffer;
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
        NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &message_buffer,
        0, NULL );
    sio_debug("%s Error occured: %s. Error: %d (%s).", type, msg, error_code, message_buffer);
    LocalFree(message_buffer);
#endif
    return error_code;
}
Example #8
0
/* 
 *  Closes the listening socket and performs cleanup of alocated resources
 */
static int sio_stop_server(SIO_SERVER * server) {
    sio_cleanup_clients(server);
    /* close listening socket */
    if (closesocket(server->socket) == SOCKET_ERROR) {
        return sio_handle_WSA_error("Canot close server socket");
    }
    /* wait for listen thread to end */
    WaitForSingleObject(server->thread, INFINITE);
    CloseHandle(server->thread);
    CloseHandle(server->clients.mutex);
    sio_debug("Server stopped");
    return 0;
}
Example #9
0
/* 
 *  Accepts clients on a socked
 *  If the socket is closed or WSA disabled the function shuts down
 */
static int sio_accept_clients(SIO_SERVER * server) {
    SOCKET new_client;
    int res = 0;
    sio_debug("Listener thread started");
    while (1) {
        new_client = accept(server->socket, NULL, NULL);
        if (server->clients.length <= 0) {
            sio_debug("Server terminating.");
            closesocket(new_client);
            res = 0;
            break;
        } else if (new_client == INVALID_SOCKET) {
            res = sio_handle_WSA_error("Error while accepting client. Stopping server.");
            break;
        } else {
            sio_lock_clients(server);
            sio_add_client(server, new_client);
            sio_unlock_clients(server);
        }
    }
    sio_debug("Listener finished");
    return res;
}
Example #10
0
void debug(void)
{
	vlist_i *it;
	pipe_s *pit;
	int i = 1;
	
	fprintf(stderr, "pipes:\n\n");
	vlist_debug(&pipes, stderr);

	for (it = pipes.head; it; it = it->next)
	{
		pit = (pipe_s *)it->data;

		fprintf(stderr, "sio[%d]:\n\n", i);
		sio_debug(&pit->sio, stderr);

		fprintf(stderr, "sock[%d]:\n\n", i);
		tcp_debug(&pit->sock, stderr);

		i++;
	}
}
Example #11
0
/* 
 *  Terminates all running servers
 *  If the module was not started using sio_init
 *  0 is returned and nothing is done.
 */
int SIOStop() {
    int last_error = 0;
    /* check status */
    if (sio_servers_initialized == 0) {
        return 0;
    }
    /* stop servers */
    last_error = sio_stop_server(&sio_stdout_server);
    if (last_error != 0) {
        return last_error;
    }
    last_error = sio_stop_server(&sio_stderr_server);
    if (last_error != 0) {
        return last_error;
    }
    /* stop WSA */
    if (sio_stop_WSA() != 0) {
        return sio_handle_WSA_error("Canot stop WSA provider");
    }
    sio_servers_initialized = 0;
    sio_debug("Socket IO provider stopped");
    return 0;
}
Example #12
0
/* 
 *  Releases Mutex acqired for current thread
 */
static void sio_unlock_clients(SIO_SERVER * server) {
    if (!ReleaseMutex(server->clients.mutex)) {
        sio_handle_system_error("Canot release mutex");
    }
    sio_debug("UNLOCK");
}