1 : /*
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
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <stdio.h>
8 : #include <stdlib.h>
9 : #include <string.h>
10 :
11 : #include "native_client/src/shared/srpc/nacl_srpc.h"
12 : #include "native_client/src/shared/srpc/nacl_srpc_internal.h"
13 :
14 : /*
15 : * ServerLoop processes the RPCs that this descriptor listens to.
16 : */
17 : static int ServerLoop(NaClSrpcService* service,
18 : NaClSrpcImcDescType socket_desc,
19 2 : void* instance_data) {
20 2 : NaClSrpcChannel* channel = NULL;
21 2 : int retval = 0;
22 :
23 : NaClSrpcLog(2, "ServerLoop(service=%p, socket_desc=%p, instance_data=%p)\n",
24 : (void*) service,
25 : (void*) socket_desc,
26 2 : (void*) instance_data);
27 : /*
28 : * SrpcChannel objects can be large due to the buffers they contain.
29 : * Hence they should not be allocated on a thread stack.
30 : */
31 2 : channel = (NaClSrpcChannel*) malloc(sizeof(*channel));
32 2 : if (NULL == channel) {
33 : NaClSrpcLog(NACL_SRPC_LOG_ERROR,
34 0 : "ServerLoop: channel malloc failed\n");
35 0 : goto cleanup;
36 : }
37 : /* Create an SRPC server listening on the new file descriptor. */
38 2 : if (!NaClSrpcServerCtor(channel, socket_desc, service, instance_data)) {
39 : NaClSrpcLog(NACL_SRPC_LOG_ERROR,
40 0 : "ServerLoop: NaClSrpcServerCtor failed\n");
41 0 : goto cleanup;
42 : }
43 : /*
44 : * Loop receiving RPCs and processing them.
45 : * The loop stops when a method requests a break out of the loop
46 : * or the IMC layer is unable to satisfy a request.
47 : */
48 2 : NaClSrpcRpcWait(channel, NULL);
49 2 : retval = 1;
50 : NaClSrpcLog(2,
51 : "ServerLoop(service=%p, socket_desc=%p, instance_data=%p) done\n",
52 : (void*) service,
53 : (void*) socket_desc,
54 2 : (void*) instance_data);
55 :
56 : cleanup:
57 2 : NaClSrpcDtor(channel);
58 2 : free(channel);
59 2 : return retval;
60 2 : }
61 :
62 : int NaClSrpcServerLoop(NaClSrpcImcDescType imc_socket_desc,
63 : const NaClSrpcHandlerDesc methods[],
64 2 : void* instance_data) {
65 : NaClSrpcService* service;
66 :
67 : /* Ensure we are passed a valid socket descriptor. */
68 2 : if (NACL_INVALID_DESCRIPTOR == imc_socket_desc) {
69 : NaClSrpcLog(NACL_SRPC_LOG_ERROR,
70 0 : "NaClSrpcServerLoop: bad imc_socket_desc\n");
71 0 : return 0;
72 : }
73 : /* Allocate the service structure. */
74 2 : service = (struct NaClSrpcService*) malloc(sizeof(*service));
75 2 : if (NULL == service) {
76 : NaClSrpcLog(NACL_SRPC_LOG_ERROR,
77 0 : "NaClSrpcServerLoop: service malloc failed\n");
78 0 : return 0;
79 : }
80 : /* Build the service descriptor. */
81 2 : if (!NaClSrpcServiceHandlerCtor(service, methods)) {
82 : NaClSrpcLog(NACL_SRPC_LOG_ERROR,
83 0 : "NaClSrpcServerLoop: NaClSrpcServiceHandlerCtor failed\n");
84 0 : free(service);
85 0 : return 0;
86 : }
87 : /* Process the RPCs. ServerLoop takes ownership of service. */
88 2 : return ServerLoop(service, imc_socket_desc, instance_data);
89 2 : }
|