void xi_delete_context( xi_context_t* context ) { if( context ) { XI_SAFE_FREE( context->api_key ); } XI_SAFE_FREE( context ); }
layer_state_t posix_asynch_io_layer_on_close( layer_connectivity_t* context ) { // prepare return value layer_state_t ret = LAYER_STATE_OK; // posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) context->self->user_data; if( shutdown( posix_asynch_data->socket_fd, SHUT_RDWR ) == -1 ) { xi_set_err( XI_SOCKET_SHUTDOWN_ERROR ); close( posix_asynch_data->socket_fd ); // just in case ret = LAYER_STATE_ERROR; goto err_handling; } // close the connection & the socket if( close( posix_asynch_data->socket_fd ) == -1 ) { xi_set_err( XI_SOCKET_CLOSE_ERROR ); ret = LAYER_STATE_ERROR; goto err_handling; } err_handling: // cleanup the memory if( posix_asynch_data ) { XI_SAFE_FREE( posix_asynch_data ); } return ret; }
void xi_delete_context( xi_context_t* context ) { assert( context != 0 && "context must not be null!" ); switch( context->protocol ) { case XI_HTTP: destroy_and_disconnect_layers( &( context->layer_chain ), CONNECTION_SCHEME_LENGTH( CONNECTION_SCHEME_1 ) ); break; default: assert( 0 && "not yet implemented!" ); break; } XI_SAFE_FREE( context->api_key ); XI_SAFE_FREE( context ); }
xi_context_t* xi_create_context( xi_protocol_t protocol, const char* api_key , int32_t feed_id ) { // allocate the structure to store new context xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) ); XI_CHECK_MEMORY( ret ); // copy given numeric parameters as is ret->protocol = protocol; ret->feed_id = feed_id; // copy string parameters carefully if( api_key ) { // duplicate the string ret->api_key = xi_str_dup( api_key ); XI_CHECK_MEMORY( ret->api_key ); } else { ret->api_key = 0; } return ret; err_handling: if( ret ) { XI_SAFE_FREE( ret ); } return 0; }
xi_context_t* xi_create_context( xi_protocol_t protocol, const char* api_key , xi_feed_id_t feed_id ) { // allocate the structure to store new context xi_context_t* ret = ( xi_context_t* ) xi_alloc( sizeof( xi_context_t ) ); XI_CHECK_MEMORY( ret ); // copy given numeric parameters as is ret->protocol = protocol; ret->feed_id = feed_id; // copy string parameters carefully if( api_key ) { // duplicate the string ret->api_key = xi_str_dup( api_key ); XI_CHECK_MEMORY( ret->api_key ); } else { ret->api_key = 0; } switch( protocol ) { case XI_HTTP: { // @TODO make a configurable pool of these // static structures allocated statically static http_layer_data_t http_layer_data; static csv_layer_data_t csv_layer_data; static xi_response_t xi_response; // clean the structures memset( &http_layer_data, 0, sizeof( http_layer_data_t ) ); memset( &csv_layer_data, 0, sizeof( csv_layer_data_t ) ); memset( &xi_response, 0, sizeof( xi_response_t ) ); // the response pointer http_layer_data.response = &xi_response; csv_layer_data.response = &xi_response; // prepare user data description void* user_datas[] = { 0, ( void* ) &http_layer_data, ( void* ) &csv_layer_data }; // create and connect layers store the information in layer_chain member ret->layer_chain = create_and_connect_layers( CONNECTION_SCHEME_1, user_datas, CONNECTION_SCHEME_LENGTH( CONNECTION_SCHEME_1 ) ); } break; default: goto err_handling; } return ret; err_handling: if( ret ) { if( ret->api_key ) { XI_SAFE_FREE( ret->api_key ); } XI_SAFE_FREE( ret ); } return 0; }
layer_state_t posix_asynch_io_layer_connect( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { XI_UNUSED( hint ); static uint16_t cs = 0; // local coroutine prereserved state xi_connection_data_t* connection_data = ( xi_connection_data_t* ) data; layer_t* layer = ( layer_t* ) context->self; posix_asynch_data_t* posix_asynch_data = ( posix_asynch_data_t* ) layer->user_data; BEGIN_CORO( cs ) xi_debug_format( "Connecting layer [%d] to the endpoint", layer->layer_type_id ); // socket specific data struct sockaddr_in name; struct hostent* hostinfo; // get the hostaddress hostinfo = gethostbyname( connection_data->address ); // if null it means that the address has not been founded if( hostinfo == NULL ) { xi_debug_logger( "Getting Host by name [failed]" ); xi_set_err( XI_SOCKET_GETHOSTBYNAME_ERROR ); goto err_handling; } xi_debug_logger( "Getting Host by name [ok]" ); // set the address and the port for further connection attempt memset( &name, 0, sizeof( struct sockaddr_in ) ); name.sin_family = AF_INET; name.sin_addr = *( ( struct in_addr* ) hostinfo->h_addr ); name.sin_port = htons( connection_data->port ); xi_debug_logger( "Connecting to the endpoint..." ); if( connect( posix_asynch_data->socket_fd, ( struct sockaddr* ) &name, sizeof( struct sockaddr ) ) == -1 ) { if( errno != EINPROGRESS ) { xi_debug_printf( "errno: %d", errno ); xi_debug_logger( "Connecting to the endpoint [failed]" ); xi_set_err( XI_SOCKET_CONNECTION_ERROR ); goto err_handling; } else { YIELD( cs, LAYER_STATE_WANT_WRITE ); // return here whenever we can write } } EXIT( cs, LAYER_STATE_OK ); err_handling: // cleanup the memory if( posix_asynch_data ) { close( posix_asynch_data->socket_fd ); } if( layer->user_data ) { XI_SAFE_FREE( layer->user_data ); } EXIT( cs, LAYER_STATE_ERROR ); END_CORO() }
layer_state_t posix_asynch_io_layer_init( layer_connectivity_t* context , const void* data , const layer_hint_t hint ) { XI_UNUSED( hint ); XI_UNUSED( data ); // PRECONDITIONS assert( context != 0 ); xi_debug_logger( "[posix_io_layer_init]" ); layer_t* layer = ( layer_t* ) context->self; posix_asynch_data_t* posix_asynch_data = xi_alloc( sizeof( posix_asynch_data_t ) ); XI_CHECK_MEMORY( posix_asynch_data ); layer->user_data = ( void* ) posix_asynch_data; xi_debug_logger( "Creating socket..." ); posix_asynch_data->socket_fd = socket( AF_INET, SOCK_STREAM, 0 ); if( posix_asynch_data->socket_fd == -1 ) { xi_debug_logger( "Socket creation [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); return 0; } xi_debug_logger( "Setting socket non blocking behaviour..." ); int flags = fcntl( posix_asynch_data->socket_fd, F_GETFL, 0 ); if( flags == -1 ) { xi_debug_logger( "Socket non blocking behaviour [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); goto err_handling; } if( fcntl( posix_asynch_data->socket_fd, F_SETFL, flags | O_NONBLOCK ) == -1 ) { xi_debug_logger( "Socket non blocking behaviour [failed]" ); xi_set_err( XI_SOCKET_INITIALIZATION_ERROR ); goto err_handling; } xi_debug_logger( "Socket creation [ok]" ); // POSTCONDITIONS assert( layer->user_data != 0 ); assert( posix_asynch_data->socket_fd != -1 ); return LAYER_STATE_OK; err_handling: // cleanup the memory if( posix_asynch_data ) { close( posix_asynch_data->socket_fd ); } if( layer->user_data ) { XI_SAFE_FREE( layer->user_data ); } return LAYER_STATE_ERROR; }