Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "nacl_io/devfs/jspipe_event_emitter.h" | |
| 6 | |
| 7 #define __STDC_FORMAT_MACROS | |
| 8 #include <errno.h> | |
| 9 #include <inttypes.h> | |
| 10 #include <string.h> | |
| 11 | |
| 12 #include <algorithm> | |
| 13 | |
| 14 #define TRACE(format, ...) \ | |
| 15 LOG_TRACE("jspipe[%s]: " format, name_.c_str(), ##__VA_ARGS__) | |
| 16 #define ERROR(format, ...) \ | |
| 17 LOG_ERROR("jspipe[%s]: " format, name_.c_str(), ##__VA_ARGS__) | |
| 18 | |
| 19 #include "nacl_io/log.h" | |
| 20 #include "nacl_io/pepper_interface.h" | |
| 21 | |
| 22 namespace { | |
| 23 const size_t kMaxPostMessageSize = 64*1024; | |
| 24 } | |
| 25 | |
| 26 namespace nacl_io { | |
| 27 | |
| 28 JSPipeEventEmitter::JSPipeEventEmitter(PepperInterface* ppapi, size_t size) | |
| 29 : input_fifo_(size), | |
| 30 post_message_buffer_size_(size), | |
| 31 bytes_sent_(0), | |
| 32 bytes_acked_(0), | |
| 33 bytes_read_(0), | |
| 34 ppapi_(ppapi) { | |
| 35 if (ppapi) { | |
| 36 messaging_iface_ = ppapi->GetMessagingInterface(); | |
|
binji
2014/05/01 20:22:31
initialize to NULL if ppapi is NULL
Sam Clegg
2014/05/01 22:16:55
Done, and added a test.
| |
| 37 var_iface_ = ppapi->GetVarInterface(); | |
| 38 array_iface_ = ppapi->GetVarArrayInterface(); | |
| 39 buffer_iface_ = ppapi->GetVarArrayBufferInterface(); | |
| 40 dict_iface_ = ppapi->GetVarDictionaryInterface(); | |
| 41 } | |
| 42 UpdateStatus_Locked(); | |
| 43 } | |
| 44 | |
| 45 void JSPipeEventEmitter::UpdateStatus_Locked() { | |
| 46 uint32_t status = 0; | |
| 47 if (!input_fifo_.IsEmpty()) | |
| 48 status |= POLLIN; | |
| 49 | |
| 50 if (GetOSpace() > 0) | |
| 51 status |= POLLOUT; | |
| 52 | |
| 53 ClearEvents_Locked(~status); | |
| 54 RaiseEvents_Locked(status); | |
| 55 } | |
| 56 | |
| 57 size_t JSPipeEventEmitter::Read_Locked(char* data, size_t len) { | |
| 58 size_t out_len = input_fifo_.Read(data, len); | |
| 59 if (out_len > 0) { | |
| 60 bytes_read_ += out_len; | |
| 61 SendAckMessage(bytes_read_); | |
|
binji
2014/05/01 20:22:31
Why ack total count instead of the amount read?
binji
2014/05/01 20:22:31
check error
Sam Clegg
2014/05/01 22:16:55
The ack messages always contain the running total.
Sam Clegg
2014/05/01 22:16:55
Done.
| |
| 62 } | |
| 63 | |
| 64 UpdateStatus_Locked(); | |
| 65 return out_len; | |
| 66 } | |
| 67 | |
| 68 Error JSPipeEventEmitter::SendWriteMessage(const void* buf, size_t count) { | |
| 69 TRACE("SendWriteMessage [%zd] total=%" PRIi64, count, bytes_sent_); | |
| 70 if (!var_iface_ || !buffer_iface_) | |
| 71 return EIO; | |
| 72 | |
| 73 // Copy payload data in a new ArrayBuffer | |
| 74 PP_Var buffer = buffer_iface_->Create(count); | |
| 75 memcpy(buffer_iface_->Map(buffer), buf, count); | |
| 76 buffer_iface_->Unmap(buffer); | |
| 77 | |
| 78 SendMessageToJS("write", buffer); | |
|
binji
2014/05/01 20:22:31
check error
Sam Clegg
2014/05/01 22:16:55
Done.
| |
| 79 | |
| 80 var_iface_->Release(buffer); | |
| 81 return 0; | |
| 82 } | |
| 83 | |
| 84 Error JSPipeEventEmitter::SetName(const char* name) { | |
| 85 // name can only be set once | |
| 86 if (!name_.empty()) | |
| 87 return EIO; | |
| 88 | |
| 89 // new name must not be empty | |
| 90 if (!name || strlen(name) == 0) | |
| 91 return EIO; | |
| 92 | |
| 93 TRACE("set name: %s", name); | |
| 94 name_ = name; | |
| 95 return 0; | |
| 96 } | |
| 97 | |
| 98 Error JSPipeEventEmitter::SendMessageToJS(const char* message_type, | |
| 99 PP_Var payload) { | |
| 100 if (!messaging_iface_ || !var_iface_ || !dict_iface_ || !array_iface_) | |
| 101 return EIO; | |
| 102 | |
| 103 // Construct two element array containing message type and the payload | |
| 104 PP_Var array = array_iface_->Create(); | |
| 105 PP_Var message_type_var = var_iface_->VarFromUtf8(message_type, | |
|
binji
2014/05/01 20:22:31
are you expecting arbitrary message types? If not,
| |
| 106 strlen(message_type)); | |
| 107 array_iface_->Set(array, 0, message_type_var); | |
|
binji
2014/05/01 20:22:31
check errors on these pepper functions
| |
| 108 array_iface_->Set(array, 1, payload); | |
| 109 var_iface_->Release(message_type_var); | |
| 110 | |
| 111 // Create dict object with pipe name as key and array as value. | |
| 112 PP_Var dict = dict_iface_->Create(); | |
| 113 PP_Var pipe_name = var_iface_->VarFromUtf8(name_.c_str(), name_.size()); | |
|
binji
2014/05/01 20:22:31
cache this in SetName because it never changes?
| |
| 114 dict_iface_->Set(dict, pipe_name, array); | |
| 115 var_iface_->Release(pipe_name); | |
| 116 var_iface_->Release(array); | |
| 117 | |
| 118 // Send the dict via PostMessage | |
| 119 messaging_iface_->PostMessage(ppapi_->GetInstance(), dict); | |
| 120 | |
| 121 // Release the dict | |
| 122 var_iface_->Release(dict); | |
| 123 return 0; | |
| 124 } | |
| 125 | |
| 126 Error JSPipeEventEmitter::SendAckMessage(int64_t byte_count) { | |
| 127 TRACE("SendAckMessage %"PRIi64, byte_count); | |
| 128 PP_Var payload; | |
| 129 payload.type = PP_VARTYPE_INT32; | |
| 130 payload.value.as_int = (int32_t)byte_count; | |
| 131 | |
| 132 return SendMessageToJS("ack", payload); | |
| 133 } | |
| 134 | |
| 135 size_t JSPipeEventEmitter::HandleJSWrite(const char* data, size_t len) { | |
| 136 size_t out_len = input_fifo_.Write(data, len); | |
| 137 UpdateStatus_Locked(); | |
| 138 return out_len; | |
| 139 } | |
| 140 | |
| 141 void JSPipeEventEmitter::HandleJSAck(int64_t byte_count) { | |
| 142 if (byte_count > bytes_sent_ || byte_count < 0) { | |
| 143 ERROR("HandleAck unexpected byte count: %"PRIi64, byte_count); | |
| 144 return; | |
| 145 } | |
| 146 | |
| 147 bytes_acked_ = byte_count; | |
| 148 TRACE("HandleAck: %" PRIi64 "/%" PRIi64, bytes_acked_, bytes_sent_); | |
| 149 UpdateStatus_Locked(); | |
| 150 } | |
| 151 | |
| 152 size_t JSPipeEventEmitter::Write_Locked(const char* data, size_t len) { | |
| 153 if (GetOSpace() == 0) | |
| 154 return -1; | |
|
binji
2014/05/01 20:22:31
should this return ssize_t then?
Sam Clegg
2014/05/01 22:16:55
Done.
| |
| 155 | |
| 156 if (len > GetOSpace()) | |
| 157 len = GetOSpace(); | |
| 158 | |
| 159 // Limit the size of the data we send with PostMessage to kMaxPostMessageSize | |
| 160 if (len > kMaxPostMessageSize) | |
| 161 len = kMaxPostMessageSize; | |
| 162 | |
| 163 SendWriteMessage(data, len); | |
|
binji
2014/05/01 20:22:31
check error
Sam Clegg
2014/05/01 22:16:55
Done.
| |
| 164 bytes_sent_ += len; | |
| 165 | |
| 166 UpdateStatus_Locked(); | |
| 167 return len; | |
| 168 } | |
| 169 | |
| 170 } // namespace nacl_io | |
| OLD | NEW |