void irecv_header() { /* HPX_ASSERT(source_ != -1); HPX_ASSERT(source_ != util::mpi_environment::rank()); */ MPI_Irecv( header_.data(), // data pointer header_.data_size_, // number of elements header_.type(), // MPI Datatype MPI_ANY_SOURCE, // Source 0, // Tag communicator_, // Communicator &request_); // Request }
typename command::response readresponse() { while( true ) { if( !readpacket() ) { COMMA_THROW( comma::exception, "expected command response, got end of stream" ); } switch( m_header->type() ) { case header::scan_type: case header::fault_type: // cannot throw yet, since need to get response first break; case header::response_type: { unsigned int id = reinterpret_cast< const commands::response_header* >( m_payload )->id() & 0x3fff; if( int( id ) != *m_commandId ) { COMMA_THROW( comma::exception, "expected response to command 0x" << std::hex << *m_commandId << ", got 0x" << id << std::dec ); } m_commandId.reset(); return *( reinterpret_cast< typename command::response* >( m_payload ) ); } default: COMMA_THROW( comma::exception, "expected command response, got packet of unknown type (0x" << std::hex << m_header->type() << std::dec ); } } }
bool readpacket() // watch performance, if bad, optimize with chunk reading { std::size_t offset = 0; if( !m_synchronized ) { bool first = true; while( offset < 4 ) // watch performance, if bad, optimize with chunk reading { m_istream->read( &m_buf[offset], 1 ); if( first && m_istream->eof() ) { return false; } first = false; if( m_istream->eof() || m_istream->bad() ) { COMMA_THROW( comma::exception, "failed to synchronize, bad stream" ); } unsigned char header_byte = reinterpret_cast<const unsigned char*>( m_header->data() )[offset]; offset = header_byte == header::sentinel_value[offset] ? offset + 1 : 0; } m_synchronized = true; // quick and dirty: synchronize once, should be enough } m_istream->read( &m_buf[0] + offset, header::size - offset ); if( m_istream->gcount() == 0 ) { return false; } if( m_istream->eof() || m_istream->bad() || m_istream->gcount() != static_cast< int >( header::size - offset ) ) { COMMA_THROW( comma::exception, "failed to read packet header" ); } if( !m_header->valid() ) { m_synchronized = false; COMMA_THROW( comma::exception, "invalid header (stream from laser went out of sync)" ); } const std::size_t size = m_header->payload_size(); if( m_buf.size() < size + header::size ) { m_buf.resize( size + header::size ); m_header = reinterpret_cast< const header* >( &m_buf[0] ); m_payload = &m_buf[0] + header::size; } m_istream->read( m_payload, size ); // todo: check payload size so that it does not go crazy? if( m_istream->eof() ) { COMMA_THROW( comma::exception, "failed to read payload of size " << m_header->payload_size() << ", end of file" ); } if( m_istream->bad() || m_istream->gcount() != int( size ) ) { COMMA_THROW( comma::exception, "failed to read payload of size " << m_header->payload_size() << ", bad stream" ); } if( m_header->type() == header::fault_type ) { m_fault = *( reinterpret_cast< fault* >( m_payload ) ); } return true; }