static void test_foreach_message_queue() { message_queue *queue = create_message_queue(); assert_true( queue != NULL ); buffer *first_buf = alloc_buffer(); append_string( first_buf, "first_buffer" ); assert_true( enqueue_message( queue, first_buf ) ); assert_int_equal( queue->length, 1 ); buffer *second_buf = alloc_buffer(); append_string( second_buf, "second_buffer" ); assert_true( enqueue_message( queue, second_buf ) ); assert_int_equal( queue->length, 2 ); buffer *third_buf = alloc_buffer(); append_string( third_buf, "third_buffer" ); assert_true( enqueue_message( queue, third_buf ) ); assert_int_equal( queue->length, 3 ); buffer *deq_buf = dequeue_message( queue ); assert_true( deq_buf == first_buf ); char *user_data = xstrdup( "user_data" ); count = 0; foreach_message_queue( queue, test_foreach_message_queue_helper, user_data ); assert_int_equal( count, 2 ); xfree( user_data ); assert_true( delete_message_queue( queue ) ); }
int flush_secure_channel( struct switch_info *sw_info ) { assert( sw_info != NULL ); assert( sw_info->send_queue != NULL ); assert( sw_info->secure_channel_fd >= 0 ); buffer *buf; ssize_t write_length; if ( sw_info->send_queue->length == 0 ) { return 0; } set_writable( sw_info->secure_channel_fd, false ); writev_args args; args.iov = xmalloc( sizeof( struct iovec ) * ( size_t ) sw_info->send_queue->length ); args.iovcnt = 0; foreach_message_queue( sw_info->send_queue, append_to_writev_args, &args ); if ( args.iovcnt == 0 ) { xfree( args.iov ); return 0; } write_length = writev( sw_info->secure_channel_fd, args.iov, args.iovcnt ); xfree( args.iov ); if ( write_length < 0 ) { if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK ) { set_writable( sw_info->secure_channel_fd, true ); return 0; } error( "Failed to send a message to secure channel ( errno = %s [%d] ).", strerror( errno ), errno ); return -1; } if ( write_length == 0 ) { return 0; } while ( ( buf = peek_message( sw_info->send_queue ) ) != NULL ) { if ( write_length == 0 ) { set_writable( sw_info->secure_channel_fd, true ); return 0; } if ( ( size_t ) write_length < buf->length ) { remove_front_buffer( buf, ( size_t ) write_length ); set_writable( sw_info->secure_channel_fd, true ); return 0; } write_length -= ( ssize_t ) buf->length; buf = dequeue_message( sw_info->send_queue ); free_buffer( buf ); } return 0; }
static void test_foreach_message_queue_if_queue_is_empty() { message_queue *queue = create_message_queue(); assert_true( queue != NULL ); char *user_data = xstrdup( "user_data" ); foreach_message_queue( queue, test_foreach_message_queue_if_queue_is_empty_helper, user_data ); assert_int_equal( count, 2 ); xfree( user_data ); assert_true( delete_message_queue( queue ) ); }