michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "chrome/common/ipc_message.h" michael@0: michael@0: #include "base/logging.h" michael@0: #include "build/build_config.h" michael@0: michael@0: #if defined(OS_POSIX) michael@0: #include "chrome/common/file_descriptor_set_posix.h" michael@0: #endif michael@0: #ifdef MOZ_TASK_TRACER michael@0: #include "GeckoTaskTracer.h" michael@0: #endif michael@0: michael@0: #ifdef MOZ_TASK_TRACER michael@0: using namespace mozilla::tasktracer; michael@0: #endif michael@0: michael@0: namespace IPC { michael@0: michael@0: //------------------------------------------------------------------------------ michael@0: michael@0: Message::~Message() { michael@0: } michael@0: michael@0: Message::Message() michael@0: : Pickle(sizeof(Header)) { michael@0: header()->routing = header()->type = header()->flags = 0; michael@0: #if defined(OS_POSIX) michael@0: header()->num_fds = 0; michael@0: #endif michael@0: #ifdef MOZ_TASK_TRACER michael@0: header()->source_event_id = 0; michael@0: header()->parent_task_id = 0; michael@0: header()->source_event_type = SourceEventType::UNKNOWN; michael@0: #endif michael@0: InitLoggingVariables(); michael@0: } michael@0: michael@0: Message::Message(int32_t routing_id, msgid_t type, PriorityValue priority, michael@0: MessageCompression compression, const char* const name) michael@0: : Pickle(sizeof(Header)) { michael@0: header()->routing = routing_id; michael@0: header()->type = type; michael@0: header()->flags = priority; michael@0: if (compression == COMPRESSION_ENABLED) michael@0: header()->flags |= COMPRESS_BIT; michael@0: #if defined(OS_POSIX) michael@0: header()->num_fds = 0; michael@0: #endif michael@0: header()->interrupt_remote_stack_depth_guess = static_cast(-1); michael@0: header()->interrupt_local_stack_depth = static_cast(-1); michael@0: header()->seqno = 0; michael@0: #if defined(OS_MACOSX) michael@0: header()->cookie = 0; michael@0: #endif michael@0: #ifdef MOZ_TASK_TRACER michael@0: header()->source_event_id = 0; michael@0: header()->parent_task_id = 0; michael@0: header()->source_event_type = SourceEventType::UNKNOWN; michael@0: #endif michael@0: InitLoggingVariables(name); michael@0: } michael@0: michael@0: Message::Message(const char* data, int data_len) : Pickle(data, data_len) { michael@0: InitLoggingVariables(); michael@0: } michael@0: michael@0: Message::Message(const Message& other) : Pickle(other) { michael@0: InitLoggingVariables(other.name_); michael@0: #if defined(OS_POSIX) michael@0: file_descriptor_set_ = other.file_descriptor_set_; michael@0: #endif michael@0: #ifdef MOZ_TASK_TRACER michael@0: header()->source_event_id = other.header()->source_event_id; michael@0: header()->parent_task_id = other.header()->parent_task_id; michael@0: header()->source_event_type = other.header()->source_event_type; michael@0: #endif michael@0: } michael@0: michael@0: void Message::InitLoggingVariables(const char* const name) { michael@0: name_ = name; michael@0: #ifdef IPC_MESSAGE_LOG_ENABLED michael@0: received_time_ = 0; michael@0: dont_log_ = false; michael@0: log_data_ = NULL; michael@0: #endif michael@0: } michael@0: michael@0: Message& Message::operator=(const Message& other) { michael@0: *static_cast(this) = other; michael@0: InitLoggingVariables(other.name_); michael@0: #if defined(OS_POSIX) michael@0: file_descriptor_set_ = other.file_descriptor_set_; michael@0: #endif michael@0: #ifdef MOZ_TASK_TRACER michael@0: header()->source_event_id = other.header()->source_event_id; michael@0: header()->parent_task_id = other.header()->parent_task_id; michael@0: header()->source_event_type = other.header()->source_event_type; michael@0: #endif michael@0: return *this; michael@0: } michael@0: michael@0: #ifdef IPC_MESSAGE_LOG_ENABLED michael@0: void Message::set_sent_time(int64_t time) { michael@0: DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0); michael@0: header()->flags |= HAS_SENT_TIME_BIT; michael@0: WriteInt64(time); michael@0: } michael@0: michael@0: int64_t Message::sent_time() const { michael@0: if ((header()->flags & HAS_SENT_TIME_BIT) == 0) michael@0: return 0; michael@0: michael@0: const char* data = end_of_payload(); michael@0: data -= sizeof(int64_t); michael@0: return *(reinterpret_cast(data)); michael@0: } michael@0: michael@0: void Message::set_received_time(int64_t time) const { michael@0: received_time_ = time; michael@0: } michael@0: #endif michael@0: michael@0: #if defined(OS_POSIX) michael@0: bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) { michael@0: // We write the index of the descriptor so that we don't have to michael@0: // keep the current descriptor as extra decoding state when deserialising. michael@0: WriteInt(file_descriptor_set()->size()); michael@0: if (descriptor.auto_close) { michael@0: return file_descriptor_set()->AddAndAutoClose(descriptor.fd); michael@0: } else { michael@0: return file_descriptor_set()->Add(descriptor.fd); michael@0: } michael@0: } michael@0: michael@0: bool Message::ReadFileDescriptor(void** iter, michael@0: base::FileDescriptor* descriptor) const { michael@0: int descriptor_index; michael@0: if (!ReadInt(iter, &descriptor_index)) michael@0: return false; michael@0: michael@0: FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get(); michael@0: if (!file_descriptor_set) michael@0: return false; michael@0: michael@0: descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index); michael@0: descriptor->auto_close = false; michael@0: michael@0: return descriptor->fd >= 0; michael@0: } michael@0: michael@0: void Message::EnsureFileDescriptorSet() { michael@0: if (file_descriptor_set_.get() == NULL) michael@0: file_descriptor_set_ = new FileDescriptorSet; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: } // namespace IPC