/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/common/ipc_message.h" #include "base/logging.h" #include "build/build_config.h" #if defined(OS_POSIX) #include "chrome/common/file_descriptor_set_posix.h" #endif #ifdef MOZ_TASK_TRACER #include "GeckoTaskTracer.h" #endif #include "mozilla/Move.h" #ifdef MOZ_TASK_TRACER using namespace mozilla::tasktracer; #endif namespace IPC { //------------------------------------------------------------------------------ Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); } Message::Message() : Pickle(sizeof(Header)) { MOZ_COUNT_CTOR(IPC::Message); header()->routing = header()->type = header()->flags = 0; #if defined(OS_POSIX) header()->num_fds = 0; #endif #ifdef MOZ_TASK_TRACER header()->source_event_id = 0; header()->parent_task_id = 0; header()->source_event_type = SourceEventType::Unknown; #endif InitLoggingVariables(); } Message::Message(int32_t routing_id, msgid_t type, NestedLevel nestedLevel, PriorityValue priority, MessageCompression compression, const char* const aName) : Pickle(sizeof(Header)) { MOZ_COUNT_CTOR(IPC::Message); header()->routing = routing_id; header()->type = type; header()->flags = nestedLevel; if (priority == HIGH_PRIORITY) header()->flags |= PRIO_BIT; if (compression == COMPRESSION_ENABLED) header()->flags |= COMPRESS_BIT; else if (compression == COMPRESSION_ALL) header()->flags |= COMPRESSALL_BIT; #if defined(OS_POSIX) header()->num_fds = 0; #endif header()->interrupt_remote_stack_depth_guess = static_cast(-1); header()->interrupt_local_stack_depth = static_cast(-1); header()->seqno = 0; #if defined(OS_MACOSX) header()->cookie = 0; #endif #ifdef MOZ_TASK_TRACER header()->source_event_id = 0; header()->parent_task_id = 0; header()->source_event_type = SourceEventType::Unknown; #endif InitLoggingVariables(aName); } Message::Message(const char* data, int data_len) : Pickle(sizeof(Header), data, data_len) { MOZ_COUNT_CTOR(IPC::Message); InitLoggingVariables(); } Message::Message(Message&& other) : Pickle(mozilla::Move(other)) { MOZ_COUNT_CTOR(IPC::Message); InitLoggingVariables(other.name_); #if defined(OS_POSIX) file_descriptor_set_ = other.file_descriptor_set_.forget(); #endif #ifdef MOZ_TASK_TRACER header()->source_event_id = other.header()->source_event_id; header()->parent_task_id = other.header()->parent_task_id; header()->source_event_type = other.header()->source_event_type; #endif } void Message::InitLoggingVariables(const char* const aName) { name_ = aName; } Message& Message::operator=(Message&& other) { *static_cast(this) = mozilla::Move(other); InitLoggingVariables(other.name_); #if defined(OS_POSIX) file_descriptor_set_.swap(other.file_descriptor_set_); #endif #ifdef MOZ_TASK_TRACER std::swap(header()->source_event_id, other.header()->source_event_id); std::swap(header()->parent_task_id, other.header()->parent_task_id); std::swap(header()->source_event_type, other.header()->source_event_type); #endif return *this; } #if defined(OS_POSIX) bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) { // We write the index of the descriptor so that we don't have to // keep the current descriptor as extra decoding state when deserialising. // Also, we rely on each file descriptor being accompanied by sizeof(int) // bytes of data in the message. See the comment for input_cmsg_buf_. WriteInt(file_descriptor_set()->size()); if (descriptor.auto_close) { return file_descriptor_set()->AddAndAutoClose(descriptor.fd); } else { return file_descriptor_set()->Add(descriptor.fd); } } bool Message::ReadFileDescriptor(PickleIterator* iter, base::FileDescriptor* descriptor) const { int descriptor_index; if (!ReadInt(iter, &descriptor_index)) return false; FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get(); if (!file_descriptor_set) return false; descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index); descriptor->auto_close = false; return descriptor->fd >= 0; } void Message::EnsureFileDescriptorSet() { if (file_descriptor_set_.get() == NULL) file_descriptor_set_ = new FileDescriptorSet; } uint32_t Message::num_fds() const { return file_descriptor_set() ? file_descriptor_set()->size() : 0; } #endif } // namespace IPC