Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include <string.h> | |
| 8 | |
| 7 #include "native_client/src/trusted/reverse_service/reverse_service.h" | 9 #include "native_client/src/trusted/reverse_service/reverse_service.h" |
| 8 | 10 |
| 9 #include "native_client/src/include/nacl_compiler_annotations.h" | 11 #include "native_client/src/include/nacl_compiler_annotations.h" |
| 10 #include "native_client/src/include/nacl_scoped_ptr.h" | 12 #include "native_client/src/include/nacl_scoped_ptr.h" |
| 11 | 13 #include "native_client/src/include/portability_io.h" |
| 12 #include "native_client/src/shared/platform/nacl_log.h" | 14 #include "native_client/src/shared/platform/nacl_log.h" |
| 13 #include "native_client/src/shared/platform/nacl_sync.h" | 15 #include "native_client/src/shared/platform/nacl_sync.h" |
| 14 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 16 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 15 #include "native_client/src/shared/platform/nacl_threads.h" | 17 #include "native_client/src/shared/platform/nacl_threads.h" |
| 16 #include "native_client/src/shared/srpc/nacl_srpc.h" | 18 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 17 | 19 |
| 20 #include "native_client/src/trusted/desc/nacl_desc_invalid.h" | |
| 21 | |
| 18 namespace { | 22 namespace { |
| 19 | 23 |
| 20 void Test(NaClSrpcRpc* rpc, | 24 void Test(NaClSrpcRpc* rpc, |
| 21 NaClSrpcArg** in_args, | 25 NaClSrpcArg** in_args, |
| 22 NaClSrpcArg** out_args, | 26 NaClSrpcArg** out_args, |
| 23 NaClSrpcClosure* done) { | 27 NaClSrpcClosure* done) { |
| 24 char *msg = in_args[0]->arrays.str; | 28 char *msg = in_args[0]->arrays.str; |
| 25 UNREFERENCED_PARAMETER(out_args); | 29 UNREFERENCED_PARAMETER(out_args); |
| 26 // use rpc->channel rather than rpc->channel->server_instance_data | 30 // use rpc->channel rather than rpc->channel->server_instance_data |
| 27 // to show that Test RPCs arrive in different channels. | 31 // to show that Test RPCs arrive in different channels. |
| 28 NaClLog(1, "Test: [%"NACL_PRIxPTR"] %s\n", | 32 NaClLog(1, "Test: [%"NACL_PRIxPTR"] %s\n", |
| 29 reinterpret_cast<uintptr_t>(rpc->channel), msg); | 33 reinterpret_cast<uintptr_t>(rpc->channel), msg); |
| 30 rpc->result = NACL_SRPC_RESULT_OK; | 34 rpc->result = NACL_SRPC_RESULT_OK; |
| 31 done->Run(done); | 35 done->Run(done); |
| 32 } | 36 } |
| 33 | 37 |
| 34 void AddChannel(NaClSrpcRpc* rpc, | 38 void AddChannel(NaClSrpcRpc* rpc, |
| 35 NaClSrpcArg** in_args, | 39 NaClSrpcArg** in_args, |
| 36 NaClSrpcArg** out_args, | 40 NaClSrpcArg** out_args, |
| 37 NaClSrpcClosure* done) { | 41 NaClSrpcClosure* done) { |
| 38 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( | 42 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( |
| 39 rpc->channel->server_instance_data); | 43 rpc->channel->server_instance_data); |
| 44 | |
| 40 UNREFERENCED_PARAMETER(in_args); | 45 UNREFERENCED_PARAMETER(in_args); |
| 41 UNREFERENCED_PARAMETER(out_args); | 46 |
| 42 NaClLog(4, "Entered AddChannel\n"); | 47 NaClLog(4, "Entered AddChannel\n"); |
| 43 out_args[0]->u.bval = service->Start(); | 48 service->Start(); |
| 49 out_args[0]->u.bval = 1; | |
|
polina
2011/06/15 00:40:29
Start now always succeeds?
bsy
2011/06/15 20:03:35
weird. reverted.
| |
| 44 NaClLog(4, "Leaving AddChannel\n"); | 50 NaClLog(4, "Leaving AddChannel\n"); |
| 45 rpc->result = NACL_SRPC_RESULT_OK; | 51 rpc->result = NACL_SRPC_RESULT_OK; |
| 46 done->Run(done); | 52 done->Run(done); |
| 47 } | 53 } |
| 48 | 54 |
| 49 void RevLog(NaClSrpcRpc* rpc, | 55 void RevLog(NaClSrpcRpc* rpc, |
| 50 NaClSrpcArg** in_args, | 56 NaClSrpcArg** in_args, |
| 51 NaClSrpcArg** out_args, | 57 NaClSrpcArg** out_args, |
| 52 NaClSrpcClosure* done) { | 58 NaClSrpcClosure* done) { |
| 53 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( | 59 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( |
| 54 rpc->channel->server_instance_data); | 60 rpc->channel->server_instance_data); |
| 55 UNREFERENCED_PARAMETER(out_args); | 61 UNREFERENCED_PARAMETER(out_args); |
| 56 char* message = in_args[0]->arrays.str; | 62 char* message = in_args[0]->arrays.str; |
| 57 | 63 |
| 58 if (NULL == service->reverse_interface()) { | 64 if (NULL == service->reverse_interface()) { |
| 59 NaClLog(1, "Log RPC, no reverse_interface. Message: %s\n", message); | 65 NaClLog(1, "Log RPC, no reverse_interface. Message: %s\n", message); |
| 60 } else { | 66 } else { |
| 61 service->reverse_interface()->Log(message); | 67 service->reverse_interface()->Log(message); |
| 62 } | 68 } |
| 63 done->Run(done); | 69 done->Run(done); |
| 64 } | 70 } |
| 65 | 71 |
| 72 // Manifest name service, internal APIs. | |
| 73 // | |
| 74 // Manifest file lookups result in read-only file descriptors with a | |
| 75 // handle. When the descriptor is closed, the service runtime must | |
| 76 // inform the plugin of this using the handle, so that the File object | |
| 77 // reference can be closed (thereby allowing the browser to delete or | |
| 78 // otherwise garbage collect the file). Files, being from the | |
| 79 // manifest, cannot be deleted. The manifest is also a read-only | |
| 80 // object, so no new entries can be made to it. | |
| 81 // | |
| 82 // Read-only proxies do not require quota support per se, since we do | |
| 83 // not limit read bandwidth. Quota support is needed for storage | |
| 84 // limits, though could also be used to limit write bandwidth (prevent | |
| 85 // disk output saturation, limit malicious code's ability to cause | |
| 86 // disk failures, especially with flash disks with limited write | |
| 87 // cycles). | |
| 88 | |
| 89 // NACL_NAME_SERVICE_LIST list::C -- enumerate all names in the manifest | |
|
polina
2011/06/15 00:40:29
NACL_MANIFEST_LIST?
bsy
2011/06/15 20:03:35
Done.
| |
| 90 void ManifestListRpc(NaClSrpcRpc* rpc, | |
| 91 NaClSrpcArg** in_args, | |
| 92 NaClSrpcArg** out_args, | |
| 93 NaClSrpcClosure* done) { | |
| 94 size_t nbytes = out_args[0]->u.count; | |
| 95 char* dest = out_args[0]->arrays.carr; | |
|
polina
2011/06/15 00:40:29
It would be more readable if you used out_args dir
bsy
2011/06/15 20:03:35
Done. Also eliminated nbytes.
| |
| 96 | |
| 97 UNREFERENCED_PARAMETER(in_args); | |
| 98 // temporary test return value. TODO(bsy) hook up to real manifest info | |
| 99 out_args[0]->u.count = SNPRINTF(dest, nbytes, | |
| 100 "This is a reply from the manifest reverse" | |
| 101 " service in the plugin."); | |
| 102 rpc->result = NACL_SRPC_RESULT_OK; | |
| 103 done->Run(done); | |
| 104 } | |
| 105 | |
| 106 // NACL_NAME_SERVICE_LOOKUP lookup:si:ihC -- look up by string name, | |
|
polina
2011/06/15 00:40:29
NACL_MANIFEST_LOOKUP?
bsy
2011/06/15 20:03:35
Done.
| |
| 107 // resulting in a handle (if name is in the preimage), a object proxy | |
| 108 // handle, and an error code. | |
| 109 void ManifestLookupRpc(NaClSrpcRpc* rpc, | |
| 110 NaClSrpcArg** in_args, | |
| 111 NaClSrpcArg** out_args, | |
| 112 NaClSrpcClosure* done) { | |
| 113 char* fname = in_args[0]->arrays.str; | |
| 114 int flags = in_args[0]->u.ival; | |
| 115 | |
| 116 NaClLog(0, "ManifestLookupRpc: %s, %d\n", fname, flags); | |
| 117 out_args[0]->u.ival = 0; // ok | |
| 118 out_args[1]->u.hval = (struct NaClDesc*) NaClDescInvalidMake(); | |
|
polina
2011/06/15 00:40:29
is this a dummy place holder for now?
polina
2011/06/15 00:51:05
It would be helpful to note this here, not just th
bsy
2011/06/15 20:03:35
yes
bsy
2011/06/15 20:03:35
Done.
| |
| 119 out_args[2]->u.count = 10; | |
| 120 strncpy(out_args[2]->arrays.carr, "123456789", 10); | |
| 121 rpc->result = NACL_SRPC_RESULT_OK; | |
| 122 done->Run(done); | |
| 123 } | |
| 124 | |
| 125 // unref:C:i -- dereferences the file by object proxy handle. The | |
|
polina
2011/06/15 00:40:29
NACL_MANIFEST_UNREF?
bsy
2011/06/15 20:03:35
Done.
| |
| 126 // file descriptor should have been closed. | |
| 127 void ManifestUnrefRpc(NaClSrpcRpc* rpc, | |
| 128 NaClSrpcArg** in_args, | |
| 129 NaClSrpcArg** out_args, | |
| 130 NaClSrpcClosure* done) { | |
| 131 char* proxy_handle = in_args[0]->arrays.carr; | |
| 132 | |
| 133 NaClLog(0, "ManifestUnrefRpc: %s\n", proxy_handle); | |
| 134 out_args[0]->u.ival = 0; // ok | |
| 135 rpc->result = NACL_SRPC_RESULT_OK; | |
| 136 done->Run(done); | |
| 137 } | |
| 138 | |
| 66 } // namespace | 139 } // namespace |
| 67 | 140 |
| 68 namespace nacl { | 141 namespace nacl { |
| 69 | 142 |
| 70 // need NaClThreadIfFactoryFunction that keeps "this" to do counting | 143 // need NaClThreadIfFactoryFunction that keeps "this" to do counting |
| 71 | 144 |
| 72 struct ReverseCountingThreadInterface { | 145 struct ReverseCountingThreadInterface { |
| 73 struct NaClThreadInterface base NACL_IS_REFCOUNT_SUBCLASS; | 146 struct NaClThreadInterface base NACL_IS_REFCOUNT_SUBCLASS; |
| 74 nacl::ReverseService* rev; | 147 nacl::ReverseService* rev; |
| 75 }; | 148 }; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 }, | 253 }, |
| 181 NaClThreadInterfaceStartThread, | 254 NaClThreadInterfaceStartThread, |
| 182 ReverseThreadIfLaunchCallback, | 255 ReverseThreadIfLaunchCallback, |
| 183 ReverseThreadIfExit, | 256 ReverseThreadIfExit, |
| 184 }; | 257 }; |
| 185 | 258 |
| 186 NaClSrpcHandlerDesc const ReverseService::handlers[] = { | 259 NaClSrpcHandlerDesc const ReverseService::handlers[] = { |
| 187 { "test:s:", Test, }, | 260 { "test:s:", Test, }, |
| 188 { "revlog:s:", RevLog, }, | 261 { "revlog:s:", RevLog, }, |
| 189 { "add_channel::b", AddChannel, }, | 262 { "add_channel::b", AddChannel, }, |
| 263 { NACL_MANIFEST_LIST, ManifestListRpc, }, | |
|
polina
2011/06/15 00:40:29
why do these require constants and not others?
bsy
2011/06/15 20:03:35
these are RPCs that are used by the manifest proxy
| |
| 264 { NACL_MANIFEST_LOOKUP, ManifestLookupRpc, }, | |
| 265 { NACL_MANIFEST_UNREF, ManifestUnrefRpc, }, | |
| 190 { NULL, NULL, }, | 266 { NULL, NULL, }, |
| 191 }; | 267 }; |
| 192 | 268 |
| 193 ReverseService::ReverseService(nacl::DescWrapper* conn_cap, | 269 ReverseService::ReverseService(nacl::DescWrapper* conn_cap, |
| 194 ReverseInterface* rif) | 270 ReverseInterface* rif) |
| 195 : service_socket_(NULL), | 271 : service_socket_(NULL), |
| 196 reverse_interface_(rif), | 272 reverse_interface_(rif), |
| 197 thread_count_(0) { | 273 thread_count_(0) { |
| 198 /* | 274 /* |
| 199 * We wait for service threads to exit before dtor'ing, so the | 275 * We wait for service threads to exit before dtor'ing, so the |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 213 ReverseService::~ReverseService() { | 289 ReverseService::~ReverseService() { |
| 214 if (thread_count_ != 0) { | 290 if (thread_count_ != 0) { |
| 215 NaClLog(LOG_FATAL, "ReverseService dtor when thread count is nonzero\n"); | 291 NaClLog(LOG_FATAL, "ReverseService dtor when thread count is nonzero\n"); |
| 216 } | 292 } |
| 217 NaClCondVarDtor(&cv_); | 293 NaClCondVarDtor(&cv_); |
| 218 NaClMutexDtor(&mu_); | 294 NaClMutexDtor(&mu_); |
| 219 } | 295 } |
| 220 | 296 |
| 221 | 297 |
| 222 bool ReverseService::Start() { | 298 bool ReverseService::Start() { |
| 299 NaClLog(4, "Entered ReverseService::Start\n"); | |
| 223 return service_socket_->StartService(reinterpret_cast<void*>(this)); | 300 return service_socket_->StartService(reinterpret_cast<void*>(this)); |
| 224 } | 301 } |
| 225 | 302 |
| 226 void ReverseService::WaitForServiceThreadsToExit() { | 303 void ReverseService::WaitForServiceThreadsToExit() { |
| 227 NaClLog(4, "ReverseService::WaitForServiceThreadsToExit\n"); | 304 NaClLog(4, "ReverseService::WaitForServiceThreadsToExit\n"); |
| 228 NaClXMutexLock(&mu_); | 305 NaClXMutexLock(&mu_); |
| 229 while (0 != thread_count_) { | 306 while (0 != thread_count_) { |
| 230 NaClXCondVarWait(&cv_, &mu_); | 307 NaClXCondVarWait(&cv_, &mu_); |
| 231 NaClLog(5, "ReverseService::WaitForServiceThreadsToExit: woke up\n"); | 308 NaClLog(5, "ReverseService::WaitForServiceThreadsToExit: woke up\n"); |
| 232 } | 309 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 252 ("ReverseService::DecrThreadCount:" | 329 ("ReverseService::DecrThreadCount:" |
| 253 " Decrementing thread count when count is zero\n")); | 330 " Decrementing thread count when count is zero\n")); |
| 254 } | 331 } |
| 255 if (0 == --thread_count_) { | 332 if (0 == --thread_count_) { |
| 256 NaClXCondVarBroadcast(&cv_); | 333 NaClXCondVarBroadcast(&cv_); |
| 257 } | 334 } |
| 258 NaClXMutexUnlock(&mu_); | 335 NaClXMutexUnlock(&mu_); |
| 259 } | 336 } |
| 260 | 337 |
| 261 } // namespace nacl | 338 } // namespace nacl |
| OLD | NEW |