OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 The Native Client 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 "native_client/src/untrusted/init/simple_service.h" |
| 6 |
| 7 namespace nacl { |
| 8 |
| 9 SimpleService::SimpleService(struct NaClSrpcHandlerDesc const *srpc_handlers) |
| 10 : handlers_(handlers) { |
| 11 } |
| 12 |
| 13 SimpleService::~SimpleService() { |
| 14 close(bound_and_cap_[0]); |
| 15 close(bound_and_cap_[1]); |
| 16 } |
| 17 |
| 18 SimpleServiceConnection *SimpleService::ConnectionFactoryWithInstanceData( |
| 19 int d, void *instance_data) { |
| 20 return new SimpleServerConnection(this, d, instance_data); |
| 21 } |
| 22 |
| 23 SimpleServiceConnection *SimpleService::ConnectionFactory(int d) { |
| 24 return ConnectionFactoryWithInstanceData(d, this); |
| 25 } |
| 26 |
| 27 SimpleServiceConnection *SimpleService::AcceptConnection() { |
| 28 SimpleServiceConnection *connection = NULL; |
| 29 |
| 30 int d = imc_accept(bound_and_cap_[0]); |
| 31 if (d == -1) { |
| 32 fprintf(stderr, "imc_accept failed\n"); |
| 33 goto out; |
| 34 } |
| 35 |
| 36 connetion = ConnectionFactory(d, &connection); |
| 37 if (connection == NULL) { |
| 38 fprintf(stderr, "ConnectionFactory failed\n"); |
| 39 goto out_socket; |
| 40 } |
| 41 |
| 42 out_socket: |
| 43 close(d); |
| 44 out: |
| 45 return connection; |
| 46 } |
| 47 |
| 48 int SimpleService::AcceptAndSpawnHandler() { |
| 49 SimpleServiceConnection *connection = AcceptConnection(&conn); |
| 50 if (connection == NULL) { |
| 51 goto abort; |
| 52 } |
| 53 |
| 54 if (!ThreadInterfaceConstructAndStartThread( |
| 55 thread_factory_fn_, |
| 56 thread_factory_data_, |
| 57 RpcHandlerBase, |
| 58 conn, |
| 59 &conn->thread_)) { |
| 60 fprintf(stderr, "no thread\n"); |
| 61 conn->Unref(); |
| 62 conn->thread_ = NULL; |
| 63 status = -EAGAIN; |
| 64 goto abort; |
| 65 } |
| 66 status = 0; |
| 67 abort: |
| 68 return status; |
| 69 } |
| 70 |
| 71 static void *AcceptThread(ThreadInterface *tif) { |
| 72 SimpleService *server = |
| 73 reinterpret_cast<SimpleService *>(tif->thread_data_); |
| 74 while (server->AcceptAndSpawnHandler() == 0) { |
| 75 continue; |
| 76 } |
| 77 server->Unref(); |
| 78 return NULL; |
| 79 } |
| 80 |
| 81 void SimpleService::RpcHandler(SimpleServiceConnection *conn) { |
| 82 conn->ServerLoop(); |
| 83 } |
| 84 |
| 85 static void *RpcHandlerBase(NaClThreadInterface *tif) { |
| 86 SimpleServiceConnection *conn = |
| 87 reinterpret_cast<SimpleServiceConnection *>(tif->thread_data_); |
| 88 |
| 89 conn->server_->RpcHandler(conn); |
| 90 conn->Unref(); |
| 91 |
| 92 return NULL; |
| 93 } |
| 94 |
| 95 SimpleServiceConnection::SimpleServiceConnection(SimpleService *server, |
| 96 int conn, |
| 97 void *instance_data) |
| 98 : server_(server->Ref()), |
| 99 connected_socket_(conn), |
| 100 instance_data_(instance_data) { |
| 101 } |
| 102 |
| 103 SimpleServiceConnection::~SimpleServiceConnection() { |
| 104 server_->Unref(); |
| 105 close(connected_socket_); |
| 106 } |
| 107 |
| 108 int SimpleServiceConnection::ServerLoop() { |
| 109 return NaClSrpcServerLoop(connected_socket_, |
| 110 server_->handlers_, |
| 111 instance_data_); |
| 112 } |
| 113 |
| 114 int SimpleServiceStartServiceThread(const SimpleService &server) { |
| 115 server.acceptor = new Thread(); |
| 116 if (!NaClThreadInterfaceConstructAndStartThread( |
| 117 server->thread_factory_fn, |
| 118 server->thread_factory_data, |
| 119 AcceptThread, |
| 120 NaClRefCountRef(&server->base), |
| 121 NACL_KERN_STACK_SIZE, |
| 122 &server->acceptor)) { |
| 123 NaClRefCountUnref(&server->base); /* undo ref in Ctor call arglist */ |
| 124 server->acceptor = NULL; |
| 125 return 0; |
| 126 } |
| 127 return 1; |
| 128 } |
| 129 |
| 130 } // namespace nacl |
OLD | NEW |