Beispiel #1
0
    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());
        }
    }