void decode_message(Parcelport & pp, boost::shared_ptr<Buffer> buffer, std::vector<util::serialization_chunk> const *chunks, bool first_message = false) { unsigned archive_flags = boost::archive::no_header; if (!pp.allow_array_optimizations()) { archive_flags |= util::disable_array_optimization; archive_flags |= util::disable_data_chunking; } else if (!pp.allow_zero_copy_optimizations()) { archive_flags |= util::disable_data_chunking; } boost::uint64_t inbound_data_size = buffer->data_size_; // protect from un-handled exceptions bubbling up try { try { // mark start of serialization util::high_resolution_timer timer; boost::int64_t overall_add_parcel_time = 0; performance_counters::parcels::data_point& data = buffer->data_point_; { // De-serialize the parcel data util::portable_binary_iarchive archive(buffer->data_, chunks, inbound_data_size, archive_flags); std::size_t parcel_count = 0; archive >> parcel_count; //-V128 for(std::size_t i = 0; i != parcel_count; ++i) { #if defined(HPX_HAVE_SECURITY) naming::gid_type parcel_id; if (pp.enable_security()) { // handle certificate and verify parcel suffix once first_message = deserialize_certificate(archive, first_message); if (!first_message && i == 0) { verify_message_suffix(buffer->data_, buffer->data_point_, parcel_id); } } // de-serialize parcel and add it to incoming parcel queue parcel p; archive >> p; // verify parcel id, but only once while handling the // first parcel if (pp.enable_security() && !first_message && i == 0 && parcel_id != p.get_parcel_id()) { // again, all hell breaks loose HPX_THROW_EXCEPTION(security_error, "decode_message", "parcel id mismatch"); return; } #else // de-serialize parcel and add it to incoming parcel queue parcel p; archive >> p; #endif // make sure this parcel ended up on the right locality HPX_ASSERT(p.get_destination_locality() == pp.here()); // be sure not to measure add_parcel as serialization time boost::int64_t add_parcel_time = timer.elapsed_nanoseconds(); pp.add_received_parcel(p); overall_add_parcel_time += timer.elapsed_nanoseconds() - add_parcel_time; } // complete received data with parcel count data.num_parcels_ = parcel_count; data.raw_bytes_ = archive.bytes_read(); } // store the time required for serialization data.serialization_time_ = timer.elapsed_nanoseconds() - overall_add_parcel_time; pp.add_received_data(data); } catch (hpx::exception const& e) { LPT_(error) << "decode_message: caught hpx::exception: " << e.what(); hpx::report_error(boost::current_exception()); } catch (boost::system::system_error const& e) { LPT_(error) << "decode_message: caught boost::system::error: " << e.what(); hpx::report_error(boost::current_exception()); } catch (boost::exception const&) { LPT_(error) << "decode_message: caught boost::exception."; hpx::report_error(boost::current_exception()); } catch (std::exception const& e) { // We have to repackage all exceptions thrown by the // serialization library as otherwise we will loose the // e.what() description of the problem, due to slicing. boost::throw_exception(boost::enable_error_info( hpx::exception(serialization_error, e.what()))); } } catch (...) { LPT_(error) << "decode_message: caught unknown exception."; hpx::report_error(boost::current_exception()); } }