| Index: native_client_sdk/src/libraries/nacl_io/devfs/jspipe_node.cc
|
| diff --git a/native_client_sdk/src/libraries/nacl_io/devfs/jspipe_node.cc b/native_client_sdk/src/libraries/nacl_io/devfs/jspipe_node.cc
|
| index 7979e33a29d8cc09a19b3e459e3664ba84c35386..5e457f3343ad4f704f4c09435fbe9ec02824f29b 100644
|
| --- a/native_client_sdk/src/libraries/nacl_io/devfs/jspipe_node.cc
|
| +++ b/native_client_sdk/src/libraries/nacl_io/devfs/jspipe_node.cc
|
| @@ -4,94 +4,94 @@
|
|
|
| #include "nacl_io/devfs/jspipe_node.h"
|
|
|
| -//#include <cstdio>
|
| #include <cstring>
|
|
|
| #include "nacl_io/devfs/dev_fs.h"
|
| #include "nacl_io/error.h"
|
| #include "nacl_io/ioctl.h"
|
| #include "nacl_io/kernel_handle.h"
|
| +#include "nacl_io/log.h"
|
| #include "nacl_io/pepper_interface.h"
|
|
|
| +#define TRACE(format, ...) LOG_TRACE("jspipe: " format, ##__VA_ARGS__)
|
| +#define ERROR(format, ...) LOG_TRACE("jspipe: " format, ##__VA_ARGS__)
|
| +
|
| +namespace {
|
| +const size_t kPostMessageBufferSize = 512*1024;
|
| +}
|
| +
|
| namespace nacl_io {
|
|
|
| -#define MAX_MESSAGE_SIZE (64*1024)
|
| +JSPipeNode::JSPipeNode(Filesystem* filesystem)
|
| + : Node(filesystem),
|
| + pipe_(new JSPipeEventEmitter(filesystem_->ppapi(), kPostMessageBufferSize))
|
| +{
|
| +}
|
| +
|
| +JSPipeEventEmitter* JSPipeNode::GetEventEmitter() {
|
| + return pipe_.get();
|
| +}
|
| +
|
| +Error JSPipeNode::Read(const HandleAttr& attr,
|
| + void* buf,
|
| + size_t count,
|
| + int* out_bytes) {
|
| + int ms = attr.IsBlocking() ? -1 : 0;
|
| +
|
| + EventListenerLock wait(GetEventEmitter());
|
| + Error err = wait.WaitOnEvent(POLLIN, ms);
|
| + if (err == ETIMEDOUT)
|
| + err = EWOULDBLOCK;
|
| + if (err)
|
| + return err;
|
| +
|
| + return GetEventEmitter()->Read_Locked(static_cast<char*>(buf), count,
|
| + out_bytes);
|
| +}
|
| +
|
| Error JSPipeNode::Write(const HandleAttr& attr,
|
| const void* buf,
|
| size_t count,
|
| int* out_bytes) {
|
| - PepperInterface* ppapi = filesystem_->ppapi();
|
| - MessagingInterface* iface = ppapi->GetMessagingInterface();
|
| - VarInterface* var_iface = ppapi->GetVarInterface();
|
| - VarArrayInterface* array_iface = ppapi->GetVarArrayInterface();
|
| - VarArrayBufferInterface* buffer_iface = ppapi->GetVarArrayBufferInterface();
|
| - if (!iface || !var_iface || !array_iface || !buffer_iface)
|
| - return ENOSYS;
|
| -
|
| - if (name_.empty())
|
| - return EIO;
|
| -
|
| - // Limit the size of the data we send with PostMessage to MAX_MESSAGE_SIZE
|
| - if (count > MAX_MESSAGE_SIZE)
|
| - count = MAX_MESSAGE_SIZE;
|
| -
|
| - // Copy data in a new ArrayBuffer
|
| - PP_Var buffer = buffer_iface->Create(count);
|
| - memcpy(buffer_iface->Map(buffer), buf, count);
|
| - buffer_iface->Unmap(buffer);
|
| -
|
| - // Construct string var containing the name of the pipe
|
| - PP_Var string = var_iface->VarFromUtf8(name_.c_str(), name_.size());
|
| -
|
| - // Construct two element array containing string and array buffer
|
| - PP_Var array = array_iface->Create();
|
| - array_iface->Set(array, 0, string);
|
| - array_iface->Set(array, 1, buffer);
|
| -
|
| - // Release our handles to the items that are now in the array
|
| - var_iface->Release(string);
|
| - var_iface->Release(buffer);
|
| -
|
| - // Send array via PostMessage
|
| - iface->PostMessage(ppapi->GetInstance(), array);
|
| -
|
| - // Release the array
|
| - var_iface->Release(array);
|
| -
|
| - *out_bytes = count;
|
| - return 0;
|
| + int ms = attr.IsBlocking() ? -1 : 0;
|
| + TRACE("write timeout=%d", ms);
|
| +
|
| + EventListenerLock wait(GetEventEmitter());
|
| + Error err = wait.WaitOnEvent(POLLOUT, ms);
|
| + if (err == ETIMEDOUT)
|
| + err = EWOULDBLOCK;
|
| + if (err)
|
| + return err;
|
| +
|
| + return GetEventEmitter()->Write_Locked(static_cast<const char*>(buf),
|
| + count, out_bytes);
|
| }
|
|
|
| Error JSPipeNode::VIoctl(int request, va_list args) {
|
| - switch (request) {
|
| - case TIOCNACLPIPENAME: {
|
| - // name can only be set once
|
| - if (!name_.empty())
|
| - return EIO;
|
| + AUTO_LOCK(node_lock_);
|
|
|
| + switch (request) {
|
| + case NACL_IOC_PIPE_SETNAME: {
|
| const char* new_name = va_arg(args, char*);
|
| - // new name must not be empty
|
| - if (!new_name || strlen(new_name) == 0)
|
| - return EIO;
|
| -
|
| - name_ = new_name;
|
| + return GetEventEmitter()->SetName(new_name);
|
| + }
|
| + case NACL_IOC_PIPE_GETISPACE: {
|
| + int* space = va_arg(args, int*);
|
| + *space = GetEventEmitter()->GetISpace();
|
| return 0;
|
| }
|
| - case TIOCNACLINPUT: {
|
| - // This ioctl is used to deliver data from javascipt into the pipe.
|
| - struct tioc_nacl_input_string* message =
|
| - va_arg(args, struct tioc_nacl_input_string*);
|
| - const char* buffer = message->buffer;
|
| - int num_bytes = message->length;
|
| - int wrote = 0;
|
| - HandleAttr data;
|
| - // Write to the underlying pipe. Calling JSPipeNode::Write
|
| - // would write using PostMessage.
|
| - int error = PipeNode::Write(data, buffer, num_bytes, &wrote);
|
| - if (error || wrote != num_bytes)
|
| - return EIO;
|
| + case NACL_IOC_PIPE_GETOSPACE: {
|
| + int* space = va_arg(args, int*);
|
| + *space = GetEventEmitter()->GetOSpace();
|
| return 0;
|
| }
|
| + case NACL_IOC_HANDLEMESSAGE: {
|
| + struct PP_Var* message = va_arg(args, struct PP_Var*);
|
| + return GetEventEmitter()->HandleJSMessage(*message);
|
| + }
|
| + default:
|
| + TRACE("unknown ioctl: %#x", request);
|
| + break;
|
| }
|
|
|
| return EINVAL;
|
|
|