11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/public/cpp/network/web_socket_read_queue.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace mojo { 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct WebSocketReadQueue::Operation { 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32_t num_bytes_; 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Callback<void(const char*)> callback_; 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebSocketReadQueue::WebSocketReadQueue(DataPipeConsumerHandle handle) 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : handle_(handle), is_waiting_(false) { 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebSocketReadQueue::~WebSocketReadQueue() { 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebSocketReadQueue::Read(uint32_t num_bytes, 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Callback<void(const char*)> callback) { 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Operation* op = new Operation; 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci op->num_bytes_ = num_bytes; 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci op->callback_ = callback; 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci queue_.push_back(op); 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!is_waiting_) 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TryToRead(); 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebSocketReadQueue::TryToRead() { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Operation* op = queue_[0]; 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const void* buffer = NULL; 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32_t bytes_read = op->num_bytes_; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MojoResult result = BeginReadDataRaw( 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle_, &buffer, &bytes_read, MOJO_READ_DATA_FLAG_ALL_OR_NONE); 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result == MOJO_RESULT_SHOULD_WAIT) { 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EndReadDataRaw(handle_, bytes_read); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Wait(); 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Ensure |op| is deleted, whether or not |this| goes away. 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<Operation> op_deleter(op); 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci queue_.weak_erase(queue_.begin()); 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result != MOJO_RESULT_OK) 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataPipeConsumerHandle handle = handle_; 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci op->callback_.Run(static_cast<const char*>(buffer)); // may delete |this| 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EndReadDataRaw(handle, bytes_read); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebSocketReadQueue::Wait() { 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_waiting_ = true; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle_watcher_.Start( 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle_, 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_HANDLE_SIGNAL_READABLE, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_DEADLINE_INDEFINITE, 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&WebSocketReadQueue::OnHandleReady, base::Unretained(this))); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebSocketReadQueue::OnHandleReady(MojoResult result) { 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci is_waiting_ = false; 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TryToRead(); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace mojo 71