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 |