blob: 116b3f3b152362e3d888c76d5ae1bbe91a5bbe49 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sync_channel.h"
#include "native_client/src/untrusted/irt/irt_dev.h"
#include "ppapi/nacl_irt/irt_interfaces.h"
#include "ppapi/nacl_irt/plugin_startup.h"
#include "ppapi/proxy/ppapi_messages.h"
#if !defined(OS_NACL_NONSFI)
namespace {
class TranslatorCompileListener : public IPC::Listener {
public:
TranslatorCompileListener(const IPC::ChannelHandle& handle,
const struct nacl_irt_pnacl_compile_funcs* funcs)
: funcs_(funcs) {
channel_ = IPC::Channel::Create(handle, IPC::Channel::MODE_SERVER, this);
CHECK(channel_->Connect());
}
// Needed for handling sync messages in OnMessageReceived().
bool Send(IPC::Message* message) {
return channel_->Send(message);
}
virtual bool OnMessageReceived(const IPC::Message& msg) {
bool handled = false;
IPC_BEGIN_MESSAGE_MAP(TranslatorCompileListener, msg)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileInit,
OnPnaclTranslatorCompileInit)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileChunk,
OnPnaclTranslatorCompileChunk)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiMsg_PnaclTranslatorCompileEnd,
OnPnaclTranslatorCompileEnd)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
private:
void OnPnaclTranslatorCompileInit(
int num_threads,
const std::vector<ppapi::proxy::SerializedHandle>& obj_files,
const std::vector<std::string>& cmd_flags,
IPC::Message* reply_msg) {
std::vector<int> obj_file_fds(obj_files.size());
for (size_t i = 0; i < obj_files.size(); ++i) {
CHECK(obj_files[i].is_file());
obj_file_fds[i] = obj_files[i].descriptor().fd;
}
std::vector<char*> cmd_flags_cstrings(cmd_flags.size());
for (size_t i = 0; i < cmd_flags.size(); ++i) {
// It's OK to use const_cast here because the callee (the translator)
// is not supposed to modify the strings. (The interface definition
// should have used "const char* const*".)
cmd_flags_cstrings[i] = const_cast<char*>(cmd_flags[i].c_str());
}
char* error_cstr = funcs_->init_callback(num_threads,
obj_file_fds.data(),
obj_file_fds.size(),
cmd_flags_cstrings.data(),
cmd_flags_cstrings.size());
bool success = !error_cstr;
std::string error_str(error_cstr ? error_cstr : "");
PpapiMsg_PnaclTranslatorCompileInit::WriteReplyParams(
reply_msg, success, error_str);
Send(reply_msg);
}
void OnPnaclTranslatorCompileChunk(const std::string& data_chunk,
IPC::Message* reply_msg) {
int result = funcs_->data_callback(data_chunk.data(), data_chunk.size());
bool success = !result;
PpapiMsg_PnaclTranslatorCompileChunk::WriteReplyParams(reply_msg, success);
Send(reply_msg);
}
void OnPnaclTranslatorCompileEnd(IPC::Message* reply_msg) {
char* error_cstr = funcs_->end_callback();
bool success = !error_cstr;
std::string error_str(error_cstr ? error_cstr : "");
PpapiMsg_PnaclTranslatorCompileEnd::WriteReplyParams(
reply_msg, success, error_str);
Send(reply_msg);
}
std::unique_ptr<IPC::Channel> channel_;
const struct nacl_irt_pnacl_compile_funcs* funcs_;
DISALLOW_COPY_AND_ASSIGN(TranslatorCompileListener);
};
void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) {
base::MessageLoop loop;
new TranslatorCompileListener(ppapi::GetRendererIPCChannelHandle(), funcs);
base::RunLoop().Run();
}
}
const struct nacl_irt_private_pnacl_translator_compile
nacl_irt_private_pnacl_translator_compile = {
ServeTranslateRequest
};
#endif // !defined(OS_NACL_NONSFI)