ipc_message.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/file_descriptor_set_posix.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::subtle::Atomic32 g_ref_num = 0; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Create a reference number for identifying IPC messages in traces. The return 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values has the reference number stored in the upper 24 bits, leaving the low 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8 bits set to 0 for use as flags. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline uint32 GetRefNumUpper24() { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::TraceLog* trace_log = base::debug::TraceLog::GetInstance(); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 pid = trace_log ? trace_log->process_id() : 0; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 count = base::subtle::NoBarrier_AtomicIncrement(&g_ref_num, 1); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The 24 bit hash is composed of 14 bits of the count and 10 bits of the 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process ID. With the current trace event buffer cap, the 14-bit count did 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not appear to wrap during a trace. Note that it is not a big deal if 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // collisions occur, as this is only used for debugging and trace analysis. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((pid << 14) | (count & 0x3fff)) << 8; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::~Message() { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::Message() 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Pickle(sizeof(Header)) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->routing = header()->type = 0; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->flags = GetRefNumUpper24(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->num_fds = 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->pad = 0; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitLoggingVariables(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::Message(int32 routing_id, uint32 type, PriorityValue priority) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Pickle(sizeof(Header)) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->routing = routing_id; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->type = type; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((priority & 0xffffff00) == 0); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->flags = priority | GetRefNumUpper24(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->num_fds = 0; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->pad = 0; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitLoggingVariables(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::Message(const char* data, int data_len) : Pickle(data, data_len) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitLoggingVariables(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message::Message(const Message& other) : Pickle(other) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitLoggingVariables(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_descriptor_set_ = other.file_descriptor_set_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::InitLoggingVariables() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_time_ = 0; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dont_log_ = false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_data_ = NULL; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Message& Message::operator=(const Message& other) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<Pickle*>(this) = other; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_descriptor_set_ = other.file_descriptor_set_; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::SetHeaderValues(int32 routing, uint32 type, uint32 flags) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should only be called when the message is already empty. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(payload_size() == 0); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->routing = routing; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->type = type; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->flags = flags; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::set_sent_time(int64 time) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((header()->flags & HAS_SENT_TIME_BIT) == 0); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header()->flags |= HAS_SENT_TIME_BIT; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteInt64(time); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 Message::sent_time() const { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((header()->flags & HAS_SENT_TIME_BIT) == 0) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data = end_of_payload(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data -= sizeof(int64); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *(reinterpret_cast<const int64*>(data)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::set_received_time(int64 time) const { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_time_ = time; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We write the index of the descriptor so that we don't have to 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keep the current descriptor as extra decoding state when deserialising. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteInt(file_descriptor_set()->size()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor.auto_close) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_descriptor_set()->AddAndAutoClose(descriptor.fd); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_descriptor_set()->Add(descriptor.fd); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::ReadFileDescriptor(PickleIterator* iter, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FileDescriptor* descriptor) const { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int descriptor_index; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ReadInt(iter, &descriptor_index)) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorSet* file_descriptor_set = file_descriptor_set_.get(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_descriptor_set) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->auto_close = true; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return descriptor->fd >= 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Message::HasFileDescriptors() const { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_descriptor_set_.get() && !file_descriptor_set_->empty(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::EnsureFileDescriptorSet() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_descriptor_set_.get() == NULL) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_descriptor_set_ = new FileDescriptorSet; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 163