Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / reverse_service / reverse_service.cc
1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #define NACL_LOG_MODULE_NAME "reverse_service"
8
9 #include "native_client/src/trusted/reverse_service/reverse_service.h"
10
11 #include <string.h>
12
13 #include <limits>
14 #include <string>
15
16 #include "native_client/src/include/nacl_compiler_annotations.h"
17 #include "native_client/src/include/nacl_scoped_ptr.h"
18 #include "native_client/src/include/portability_io.h"
19 #include "native_client/src/shared/platform/nacl_check.h"
20 #include "native_client/src/shared/platform/nacl_host_desc.h"
21 #include "native_client/src/shared/platform/nacl_log.h"
22 #include "native_client/src/shared/platform/nacl_sync.h"
23 #include "native_client/src/shared/platform/nacl_sync_checked.h"
24 #include "native_client/src/shared/platform/nacl_threads.h"
25 #include "native_client/src/shared/srpc/nacl_srpc.h"
26
27 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
28 #include "native_client/src/trusted/desc/nacl_desc_io.h"
29
30 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
31 #include "native_client/src/trusted/validator/nacl_file_info.h"
32
33 namespace {
34
35 // ReverseInterfaceWrapper wraps a C++ interface and provides
36 // C-callable wrapper functions for use by the underlying C
37 // implementation.
38
39 struct ReverseInterfaceWrapper {
40   NaClReverseInterface base NACL_IS_REFCOUNT_SUBCLASS;
41   nacl::ReverseInterface* iface;
42 };
43
44 void StartupInitializationComplete(NaClReverseInterface* self) {
45   ReverseInterfaceWrapper* wrapper =
46       reinterpret_cast<ReverseInterfaceWrapper*>(self);
47   if (NULL == wrapper->iface) {
48     NaClLog(1, "StartupInitializationComplete, no reverse_interface.\n");
49   } else {
50     wrapper->iface->StartupInitializationComplete();
51   }
52 }
53
54 int OpenManifestEntry(NaClReverseInterface* self,
55                       char const* url_key,
56                       struct NaClFileInfo* info) {
57   ReverseInterfaceWrapper* wrapper =
58       reinterpret_cast<ReverseInterfaceWrapper*>(self);
59   if (NULL == wrapper->iface) {
60     NaClLog(1, "OpenManifestEntry, no reverse_interface.\n");
61     return 0;
62   }
63   return wrapper->iface->OpenManifestEntry(nacl::string(url_key), info);
64 }
65
66 void ReportCrash(NaClReverseInterface* self) {
67   ReverseInterfaceWrapper* wrapper =
68       reinterpret_cast<ReverseInterfaceWrapper*>(self);
69   if (NULL == wrapper->iface) {
70     NaClLog(1, "ReportCrash, no reverse_interface.\n");
71   } else {
72     wrapper->iface->ReportCrash();
73   }
74 }
75
76 void ReportExitStatus(NaClReverseInterface* self,
77                       int exit_status) {
78   ReverseInterfaceWrapper* wrapper =
79       reinterpret_cast<ReverseInterfaceWrapper*>(self);
80   if (NULL == wrapper->iface) {
81     NaClLog(1, "ReportExitStatus, no reverse_interface.\n");
82   } else {
83     wrapper->iface->ReportExitStatus(exit_status);
84   }
85 }
86
87 void DoPostMessage(NaClReverseInterface* self,
88                    char const* message,
89                    size_t message_bytes) {
90   ReverseInterfaceWrapper* wrapper =
91       reinterpret_cast<ReverseInterfaceWrapper*>(self);
92   if (NULL == wrapper->iface) {
93     NaClLog(1, "DoPostMessage, no reverse_interface.\n");
94   } else {
95     wrapper->iface->DoPostMessage(nacl::string(message, message_bytes));
96   }
97 }
98
99 int CreateProcess(NaClReverseInterface* self,
100                   NaClDesc** out_sock_addr,
101                   NaClDesc** out_app_addr) {
102   ReverseInterfaceWrapper* wrapper =
103       reinterpret_cast<ReverseInterfaceWrapper*>(self);
104   if (NULL == wrapper->iface) {
105     NaClLog(1, "CreateProcess, no reverse_interface.\n");
106     return -NACL_ABI_EAGAIN;
107   }
108
109   int status;
110   nacl::DescWrapper* sock_addr;
111   nacl::DescWrapper* app_addr;
112   if (0 == (status = wrapper->iface->CreateProcess(&sock_addr, &app_addr))) {
113     *out_sock_addr = sock_addr->desc();
114     *out_app_addr = app_addr->desc();
115   }
116   return status;
117 }
118
119 class CreateProcessFunctorBinder : public nacl::CreateProcessFunctorInterface {
120  public:
121   CreateProcessFunctorBinder(void (*functor)(void* functor_state,
122                                              NaClDesc* out_sock_addr,
123                                              NaClDesc* out_app_addr,
124                                              int32_t out_pid_or_errno),
125                              void* functor_state)
126       : functor_(functor), state_(functor_state) {}
127
128   virtual void Results(nacl::DescWrapper* out_sock_addr,
129                        nacl::DescWrapper* out_app_addr,
130                        int32_t out_pid_or_errno) {
131     functor_(state_, out_sock_addr->desc(), out_app_addr->desc(),
132              out_pid_or_errno);
133   }
134  private:
135   void (*functor_)(void*, NaClDesc*, NaClDesc*, int32_t);
136   void* state_;
137 };
138
139 void CreateProcessFunctorResult(NaClReverseInterface* self,
140                                 void (*functor)(void* functor_state,
141                                                 NaClDesc* out_sock_addr,
142                                                 NaClDesc* out_app_addr,
143                                                 int32_t out_pid_or_errno),
144                                 void *functor_state) {
145   ReverseInterfaceWrapper* wrapper =
146       reinterpret_cast<ReverseInterfaceWrapper*>(self);
147
148   CreateProcessFunctorBinder callback(functor, functor_state);
149   wrapper->iface->CreateProcessFunctorResult(&callback);
150 }
151
152 void FinalizeProcess(NaClReverseInterface* self,
153                      int32_t pid) {
154   ReverseInterfaceWrapper* wrapper =
155       reinterpret_cast<ReverseInterfaceWrapper*>(self);
156
157   wrapper->iface->FinalizeProcess(pid);
158 }
159
160 int64_t RequestQuotaForWrite(NaClReverseInterface* self,
161                              char const* file_id,
162                              int64_t offset,
163                              int64_t length) {
164   ReverseInterfaceWrapper* wrapper =
165       reinterpret_cast<ReverseInterfaceWrapper*>(self);
166   if (NULL == wrapper->iface) {
167     NaClLog(1, "RequestQuotaForWrite, no reverse_interface.\n");
168     return 0;
169   }
170   return wrapper->iface->RequestQuotaForWrite(
171       nacl::string(file_id), offset, length);
172 }
173
174 void ReverseInterfaceWrapperDtor(NaClRefCount* vself) {
175   ReverseInterfaceWrapper* self =
176       reinterpret_cast<ReverseInterfaceWrapper*>(vself);
177
178   self->iface->Unref();
179   self->iface = NULL;
180
181   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
182   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
183 }
184
185 static NaClReverseInterfaceVtbl const kReverseInterfaceWrapperVtbl = {
186   {
187     ReverseInterfaceWrapperDtor,
188   },
189   StartupInitializationComplete,
190   OpenManifestEntry,
191   ReportCrash,
192   ReportExitStatus,
193   DoPostMessage,
194   CreateProcess,
195   CreateProcessFunctorResult,
196   FinalizeProcess,
197   RequestQuotaForWrite,
198 };
199
200 int ReverseInterfaceWrapperCtor(ReverseInterfaceWrapper* self,
201                                 nacl::ReverseInterface* itf) {
202   NaClLog(4,
203           "ReverseInterfaceWrapperCtor: self 0x%" NACL_PRIxPTR "\n",
204           reinterpret_cast<uintptr_t>(self));
205   if (!NaClReverseInterfaceCtor_protected(
206         reinterpret_cast<NaClReverseInterface*>(&self->base))) {
207     NaClLog(4, "ReverseInterfaceWrapperCtor:"
208             " NaClReverseInterfaceCtor_protected failed\n");
209     return 0;
210   }
211   self->iface = itf;
212
213   NACL_VTBL(NaClRefCount, self) =
214      reinterpret_cast<NaClRefCountVtbl const*>(&kReverseInterfaceWrapperVtbl);
215
216   NaClLog(4, "VTBL\n");
217   NaClLog(4, "Leaving ReverseInterfaceWrapperCtor\n");
218   return 1;
219 }
220
221 }  // namespace
222
223 namespace nacl {
224
225 ReverseService::ReverseService(DescWrapper* conn_cap,
226                                ReverseInterface* rif)
227   : service_(NULL),
228     reverse_interface_(rif) {
229   NaClLog(4, "ReverseService::ReverseService ctor invoked\n");
230
231   ReverseInterfaceWrapper* wrapper =
232       reinterpret_cast<ReverseInterfaceWrapper*>(malloc(sizeof *wrapper));
233   if (NULL == wrapper) {
234     NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
235   }
236   if (!ReverseInterfaceWrapperCtor(wrapper, rif)) {
237     NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
238             "ReverseInterfaceWrapperCtor failed\n");
239   }
240
241   service_ = reinterpret_cast<NaClReverseService*>(malloc(sizeof *service_));
242   if (NULL == service_) {
243     NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
244   }
245   if (!NaClReverseServiceCtor(service_,
246                               reinterpret_cast<NaClReverseInterface*>(wrapper),
247                               conn_cap->desc())) {
248     NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
249             "NaClReverseServiceCtor failed\n");
250   }
251 }
252
253 ReverseService::~ReverseService() {
254   NaClRefCountUnref(reinterpret_cast<struct NaClRefCount*>(service_));
255   service_ = NULL;
256 }
257
258 bool ReverseService::Start(bool crash_report) {
259   return NACL_VTBL(NaClReverseService, service_)->Start(
260       service_, crash_report);
261 }
262
263 void ReverseService::WaitForServiceThreadsToExit() {
264   NACL_VTBL(NaClReverseService, service_)->WaitForServiceThreadsToExit(
265       service_);
266 }
267
268 void ReverseService::IncrThreadCount() {
269   NACL_VTBL(NaClReverseService, service_)->ThreadCountIncr(service_);
270 }
271
272 void ReverseService::DecrThreadCount() {
273   NACL_VTBL(NaClReverseService, service_)->ThreadCountDecr(service_);
274 }
275
276 }  // namespace nacl