raw_channel.cc revision 0de6073388f4e2780db8536178b129cd8f6ab386
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/system/raw_channel.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <string.h> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm> 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/location.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/stl_util.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/system/message_in_transit.h" 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/system/transport_data.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace mojo { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace system { 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const size_t kReadSize = 4096; 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// RawChannel::ReadBuffer ------------------------------------------------------ 250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)RawChannel::ReadBuffer::ReadBuffer() 270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) : buffer_(kReadSize), 280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) num_valid_bytes_(0) { 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)RawChannel::ReadBuffer::~ReadBuffer() { 320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RawChannel::ReadBuffer::GetBuffer(char** addr, size_t* size) { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_GE(buffer_.size(), num_valid_bytes_ + kReadSize); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *addr = &buffer_[0] + num_valid_bytes_; 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *size = kReadSize; 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 400de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// RawChannel::WriteBuffer ----------------------------------------------------- 410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)RawChannel::WriteBuffer::WriteBuffer(size_t serialized_platform_handle_size) 430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) : serialized_platform_handle_size_(serialized_platform_handle_size), 440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) platform_handles_offset_(0), 450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) data_offset_(0) { 460de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)RawChannel::WriteBuffer::~WriteBuffer() { 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) STLDeleteElements(&message_queue_); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 520de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)bool RawChannel::WriteBuffer::HavePlatformHandlesToSend() const { 530de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (message_queue_.empty()) 540de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const TransportData* transport_data = 570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) message_queue_.front()->transport_data(); 580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (!transport_data) 590de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::vector<embedder::PlatformHandle>* all_platform_handles = 620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) transport_data->platform_handles(); 630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (!all_platform_handles) { 640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_EQ(platform_handles_offset_, 0u); 650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 660de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (platform_handles_offset_ >= all_platform_handles->size()) { 680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_EQ(platform_handles_offset_, all_platform_handles->size()); 690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 710de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 720de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return true; 730de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 740de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 750de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)void RawChannel::WriteBuffer::GetPlatformHandlesToSend( 760de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t* num_platform_handles, 770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) embedder::PlatformHandle** platform_handles, 780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) void** serialization_data) { 790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK(HavePlatformHandlesToSend()); 800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) TransportData* transport_data = message_queue_.front()->transport_data(); 820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) std::vector<embedder::PlatformHandle>* all_platform_handles = 830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) transport_data->platform_handles(); 840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) *num_platform_handles = 850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) all_platform_handles->size() - platform_handles_offset_; 860de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) *platform_handles = &(*all_platform_handles)[platform_handles_offset_]; 870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t serialization_data_offset = 880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) transport_data->platform_handle_table_offset(); 890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_GT(serialization_data_offset, 0u); 900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) serialization_data_offset += 910de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) platform_handles_offset_ * serialized_platform_handle_size_; 920de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) *serialization_data = 930de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) static_cast<char*>(transport_data->buffer()) + serialization_data_offset; 940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const { 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffers->clear(); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (message_queue_.empty()) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MessageInTransit* message = message_queue_.front(); 1030de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_LT(data_offset_, message->total_size()); 1040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t bytes_to_write = message->total_size() - data_offset_; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t transport_data_buffer_size = message->transport_data() ? 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) message->transport_data()->buffer_size() : 0; 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!transport_data_buffer_size) { 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Only write from the main buffer. 1110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_LT(data_offset_, message->main_buffer_size()); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE(bytes_to_write, message->main_buffer_size()); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Buffer buffer = { 1140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) static_cast<const char*>(message->main_buffer()) + data_offset_, 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_to_write}; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffers->push_back(buffer); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (data_offset_ >= message->main_buffer_size()) { 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Only write from the transport data buffer. 1220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_LT(data_offset_ - message->main_buffer_size(), 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) transport_data_buffer_size); 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_LE(bytes_to_write, transport_data_buffer_size); 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Buffer buffer = { 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static_cast<const char*>(message->transport_data()->buffer()) + 1270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (data_offset_ - message->main_buffer_size()), 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_to_write}; 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffers->push_back(buffer); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Write from both buffers. 1340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_EQ(bytes_to_write, message->main_buffer_size() - data_offset_ + 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) transport_data_buffer_size); 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Buffer buffer1 = { 1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) static_cast<const char*>(message->main_buffer()) + data_offset_, 1380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) message->main_buffer_size() - data_offset_ 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffers->push_back(buffer1); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Buffer buffer2 = { 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static_cast<const char*>(message->transport_data()->buffer()), 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) transport_data_buffer_size 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffers->push_back(buffer2); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1480de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// RawChannel ------------------------------------------------------------------ 1490de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochRawChannel::RawChannel() 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : message_loop_for_io_(NULL), 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate_(NULL), 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_stopped_(false), 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_stopped_(false), 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_(this) { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)RawChannel::~RawChannel() { 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!read_buffer_); 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!write_buffer_); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // No need to take the |write_lock_| here -- if there are still weak pointers 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // outstanding, then we're hosed anyway (since we wouldn't be able to 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // invalidate them cleanly, since we might not be on the I/O thread). 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!weak_ptr_factory_.HasWeakPtrs()); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool RawChannel::Init(Delegate* delegate) { 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(delegate); 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!delegate_); 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delegate_ = delegate; 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_IO); 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!message_loop_for_io_); 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch message_loop_for_io_ = 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static_cast<base::MessageLoopForIO*>(base::MessageLoop::current()); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // No need to take the lock. No one should be using us yet. 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!read_buffer_); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_.reset(new ReadBuffer); 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!write_buffer_); 1830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_.reset(new WriteBuffer(GetSerializedPlatformHandleSize())); 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!OnInit()) { 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate_ = NULL; 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu message_loop_for_io_ = NULL; 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu read_buffer_.reset(); 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu write_buffer_.reset(); 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ScheduleRead() == IO_PENDING; 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RawChannel::Shutdown() { 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_); 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoLock locker(write_lock_); 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LOG_IF(WARNING, !write_buffer_->message_queue_.empty()) 202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << "Shutting down RawChannel with write buffer nonempty"; 203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Reset the delegate so that it won't receive further calls. 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate_ = NULL; 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_stopped_ = true; 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_stopped_ = true; 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_.InvalidateWeakPtrs(); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnShutdownNoLock(read_buffer_.Pass(), write_buffer_.Pass()); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Reminder: This must be thread-safe. 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool RawChannel::WriteMessage(scoped_ptr<MessageInTransit> message) { 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(message); 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoLock locker(write_lock_); 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (write_stopped_) 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!write_buffer_->message_queue_.empty()) { 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_buffer_->message_queue_.push_back(message.release()); 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_buffer_->message_queue_.push_front(message.release()); 2270de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_EQ(write_buffer_->data_offset_, 0u); 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t platform_handles_written = 0; 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t bytes_written = 0; 2310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) IOResult io_result = WriteNoLock(&platform_handles_written, &bytes_written); 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (io_result == IO_PENDING) 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = OnWriteCompletedNoLock(io_result == IO_SUCCEEDED, 2360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) platform_handles_written, 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_written); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!result) { 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Even if we're on the I/O thread, don't call |OnFatalError()| in the 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // nested context. 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) message_loop_for_io_->PostTask( 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&RawChannel::CallOnFatalError, 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Delegate::FATAL_ERROR_FAILED_WRITE)); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return result; 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 251effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Reminder: This must be thread-safe. 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool RawChannel::IsWriteBufferEmpty() { 253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::AutoLock locker(write_lock_); 254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return write_buffer_->message_queue_.empty(); 255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)RawChannel::ReadBuffer* RawChannel::read_buffer() { 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return read_buffer_.get(); 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)RawChannel::WriteBuffer* RawChannel::write_buffer_no_lock() { 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_lock_.AssertAcquired(); 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return write_buffer_.get(); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RawChannel::OnReadCompleted(bool result, size_t bytes_read) { 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_); 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (read_stopped_) { 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IOResult io_result = result ? IO_SUCCEEDED : IO_FAILED; 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Keep reading data in a loop, and dispatch messages if enough data is 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // received. Exit the loop if any of the following happens: 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // - one or more messages were dispatched; 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // - the last read failed, was a partial read or would block; 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // - |Shutdown()| was called. 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) do { 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (io_result != IO_SUCCEEDED) { 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_stopped_ = true; 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CallOnFatalError(Delegate::FATAL_ERROR_FAILED_READ); 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_->num_valid_bytes_ += bytes_read; 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatch all the messages that we can. 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool did_dispatch_message = false; 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Tracks the offset of the first undispatched message in |read_buffer_|. 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Currently, we copy data to ensure that this is zero at the beginning. 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t read_buffer_start = 0; 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t remaining_bytes = read_buffer_->num_valid_bytes_; 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t message_size; 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note that we rely on short-circuit evaluation here: 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // - |read_buffer_start| may be an invalid index into 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |read_buffer_->buffer_| if |remaining_bytes| is zero. 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // - |message_size| is only valid if |GetNextMessageSize()| returns true. 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Use |message_size| more intelligently (e.g., to request the 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // next read). 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Validate that |message_size| is sane. 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (remaining_bytes > 0 && 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MessageInTransit::GetNextMessageSize( 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &read_buffer_->buffer_[read_buffer_start], remaining_bytes, 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &message_size) && 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remaining_bytes >= message_size) { 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MessageInTransit::View 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) message_view(message_size, &read_buffer_->buffer_[read_buffer_start]); 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(message_view.total_size(), message_size); 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatch the message. 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(delegate_); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) delegate_->OnReadMessage(message_view); 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (read_stopped_) { 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |Shutdown()| was called in |OnReadMessage()|. 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Add test for this case. 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) did_dispatch_message = true; 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Update our state. 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_start += message_size; 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remaining_bytes -= message_size; 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (read_buffer_start > 0) { 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Move data back to start. 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_->num_valid_bytes_ = remaining_bytes; 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (read_buffer_->num_valid_bytes_ > 0) { 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) memmove(&read_buffer_->buffer_[0], 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &read_buffer_->buffer_[read_buffer_start], remaining_bytes); 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_start = 0; 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (read_buffer_->buffer_.size() - read_buffer_->num_valid_bytes_ < 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kReadSize) { 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Use power-of-2 buffer sizes. 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Make sure the buffer doesn't get too large (and enforce the 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // maximum message size to whatever extent necessary). 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): We may often be able to peek at the header and get the real 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // required extra space (which may be much bigger than |kReadSize|). 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t new_size = std::max(read_buffer_->buffer_.size(), kReadSize); 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (new_size < read_buffer_->num_valid_bytes_ + kReadSize) 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new_size *= 2; 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): It's suboptimal to zero out the fresh memory. 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) read_buffer_->buffer_.resize(new_size, 0); 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (1) If we dispatched any messages, stop reading for now (and let the 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // message loop do its thing for another round). 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Is this the behavior we want? (Alternatives: i. Dispatch only 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // a single message. Risks: slower, more complex if we want to avoid lots of 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // copying. ii. Keep reading until there's no more data and dispatch all the 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // messages we can. Risks: starvation of other users of the message loop.) 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (2) If we didn't max out |kReadSize|, stop reading for now. 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool schedule_for_later = did_dispatch_message || bytes_read < kReadSize; 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bytes_read = 0; 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) io_result = schedule_for_later ? ScheduleRead() : Read(&bytes_read); 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } while (io_result != IO_PENDING); 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)void RawChannel::OnWriteCompleted(bool result, 3680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t platform_handles_written, 3690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t bytes_written) { 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_); 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool did_fail = false; 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoLock locker(write_lock_); 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(write_stopped_, write_buffer_->message_queue_.empty()); 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (write_stopped_) { 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3820de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) did_fail = !OnWriteCompletedNoLock(result, 3830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) platform_handles_written, 3840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) bytes_written); 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (did_fail) 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CallOnFatalError(Delegate::FATAL_ERROR_FAILED_WRITE); 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RawChannel::CallOnFatalError(Delegate::FatalError fatal_error) { 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_); 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(vtl): Add a "write_lock_.AssertNotAcquired()"? 3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (delegate_) 3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delegate_->OnFatalError(fatal_error); 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)bool RawChannel::OnWriteCompletedNoLock(bool result, 3990de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t platform_handles_written, 4000de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) size_t bytes_written) { 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_lock_.AssertAcquired(); 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!write_stopped_); 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!write_buffer_->message_queue_.empty()); 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result) { 4070de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->platform_handles_offset_ += platform_handles_written; 4080de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->data_offset_ += bytes_written; 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MessageInTransit* message = write_buffer_->message_queue_.front(); 4110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (write_buffer_->data_offset_ >= message->total_size()) { 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Complete write. 4130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK_EQ(write_buffer_->data_offset_, message->total_size()); 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_buffer_->message_queue_.pop_front(); 415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delete message; 4160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->platform_handles_offset_ = 0; 4170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->data_offset_ = 0; 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (write_buffer_->message_queue_.empty()) 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Schedule the next write. 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) IOResult io_result = ScheduleWriteNoLock(); 425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (io_result == IO_PENDING) 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(io_result, IO_FAILED); 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) write_stopped_ = true; 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) STLDeleteElements(&write_buffer_->message_queue_); 4320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->platform_handles_offset_ = 0; 4330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) write_buffer_->data_offset_ = 0; 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace system 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace mojo 439