LCOV - code coverage report
Current view: directory - src/shared/srpc - nacl_srpc.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 105 89 84.8 %
Date: 2014-10-23 Functions: 0 0 -

       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                 : /*
       8                 :  * NaCl service library.  a primitive rpc library
       9                 :  */
      10                 : 
      11                 : #include <stdarg.h>
      12                 : #include <stdlib.h>
      13                 : #include <string.h>
      14                 : 
      15                 : #ifndef __native_client__
      16                 : #include "native_client/src/include/portability.h"
      17                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      18                 : #endif  /* __native_client__ */
      19                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      20                 : #include "native_client/src/shared/platform/nacl_check.h"
      21                 : #include "native_client/src/shared/srpc/nacl_srpc_internal.h"
      22                 : #include "native_client/src/shared/srpc/nacl_srpc_message.h"
      23                 : 
      24                 : /*
      25                 :  * Service discovery is used to build an interface description that
      26                 :  * is searched for rpc dispatches.
      27                 :  */
      28              55 : static NaClSrpcService* BuildClientService(NaClSrpcChannel* channel) {
      29              55 :   NaClSrpcArg*         ins[] = { NULL };
      30                 :   NaClSrpcArg          out_carray;
      31                 :   NaClSrpcArg*         outs[2];
      32              55 :   NaClSrpcService*     tmp_service = NULL;
      33              55 :   NaClSrpcService*     service = NULL;
      34              55 :   NaClSrpcHandlerDesc  basic_services[] = { { NULL, NULL } };
      35                 :   NaClSrpcError        service_discovery_result;
      36              55 :   NaClSrpcService*     returned_service = NULL;
      37                 : 
      38                 :   /*
      39                 :    * Service discovery requires a temporary setting of channel->client.
      40                 :    * To ensure that this does not clobber a previous setting, enforce
      41                 :    * a precondition that it is NULL beforehand.
      42                 :    */
      43              55 :   CHECK(NULL == channel->client);
      44                 :   /* Set up the output parameters for service discovery. */
      45              55 :   NaClSrpcArgCtor(&out_carray);
      46              55 :   outs[0] = &out_carray;
      47              55 :   outs[1] = NULL;
      48              55 :   out_carray.tag = NACL_SRPC_ARG_TYPE_CHAR_ARRAY;
      49              55 :   out_carray.u.count = NACL_SRPC_MAX_SERVICE_DISCOVERY_CHARS;
      50                 :   /*
      51                 :    * Add one guaranteed NUL byte to make sure the string will be NUL-terminated.
      52                 :    */
      53              55 :   out_carray.arrays.carr = calloc(NACL_SRPC_MAX_SERVICE_DISCOVERY_CHARS + 1, 1);
      54              55 :   if (NULL == out_carray.arrays.carr) {
      55               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
      56                 :                 "BuildClientService(channel=%p):"
      57                 :                 " service discovery malloc failed\n",
      58                 :                 (void*) channel);
      59               0 :     goto cleanup;
      60                 :   }
      61                 :   /* Set up the basic service descriptor to make the service discovery call. */
      62              55 :   tmp_service = (NaClSrpcService*) malloc(sizeof(*tmp_service));
      63              55 :   if (NULL == tmp_service) {
      64               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
      65                 :                 "BuildClientService(channel=%p):"
      66                 :                 " temporary service malloc failed\n",
      67                 :                 (void*) channel);
      68               0 :     goto cleanup;
      69                 :   }
      70              55 :   if (!NaClSrpcServiceHandlerCtor(tmp_service, basic_services)) {
      71               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
      72                 :                 "BuildClientService(channel=%p):"
      73                 :                 " NaClSrpcServiceHandlerCtor failed\n",
      74                 :                 (void*) channel);
      75               0 :     free(tmp_service);
      76               0 :     tmp_service = NULL;
      77               0 :     goto cleanup;
      78                 :   }
      79                 :   /* Temporarily assign channel->client to allow Invoke. */
      80              55 :   channel->client = tmp_service;
      81                 :   /* Invoke service discovery, getting description string */
      82              55 :   service_discovery_result = NaClSrpcInvokeV(channel, 0, ins, outs);
      83                 :   /* Disconnect the temporary service. */
      84              50 :   channel->client = NULL;
      85              50 :   if (NACL_SRPC_RESULT_OK != service_discovery_result) {
      86               1 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
      87                 :                 "BuildClientService(channel=%p):"
      88                 :                 " service discovery invoke failed\n",
      89                 :                 (void*) channel);
      90               1 :     goto cleanup;
      91                 :   }
      92                 :   /* Allocate the real service. */
      93              49 :   service = (NaClSrpcService*) malloc(sizeof(*service));
      94              49 :   if (NULL == service) {
      95               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
      96                 :                 "BuildClientService(channel=%p):"
      97                 :                 " service discovery malloc failed\n",
      98                 :                 (void*) channel);
      99               0 :     goto cleanup;
     100                 :   }
     101                 :   /* Build the real service from the resulting string. */
     102              49 :   if (!NaClSrpcServiceStringCtor(service, out_carray.arrays.carr)) {
     103               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
     104                 :                 "BuildClientService(channel=%p):"
     105                 :                 " NaClSrpcServiceStringCtor failed\n",
     106                 :                 (void*) channel);
     107               0 :     goto cleanup;
     108                 :   }
     109                 :   /* Caller takes ownership of service. */
     110              49 :   returned_service = service;
     111              49 :   service = NULL;
     112                 :  cleanup:
     113              50 :   free(service);
     114              50 :   NaClSrpcServiceDtor(tmp_service);
     115              50 :   free(tmp_service);
     116              50 :   free(out_carray.arrays.carr);
     117              50 :   return returned_service;
     118                 : }
     119                 : 
     120                 : /*
     121                 :  * The constructors and destructor.
     122                 :  * Clients and Servers are both NaClSrpcChannels, but they are constructed
     123                 :  * by different methods reflecting how they get their table of rpc methods.
     124                 :  */
     125                 : 
     126              80 : void NaClSrpcChannelInitialize(NaClSrpcChannel* channel) {
     127              80 :   channel->message_channel = NULL;
     128              80 :   channel->server = NULL;
     129              80 :   channel->client = NULL;
     130              80 :   channel->server_instance_data = NULL;
     131              80 : }
     132                 : 
     133              80 : static int NaClSrpcChannelCtorHelper(NaClSrpcChannel* channel,
     134                 :                                      NaClSrpcImcDescType handle) {
     135              80 :   NaClSrpcLog(1,
     136                 :               "NaClSrpcChannelCtorHelper(channel=%p, handle=%p)\n",
     137                 :               (void*) channel,
     138                 :               (void*) handle);
     139                 :   /* Initialize the channel to allow errors to be handled. */
     140              80 :   NaClSrpcChannelInitialize(channel);
     141                 :   /* Create the message fragmentation layer. */
     142              80 :   channel->message_channel = NaClSrpcMessageChannelNew(handle);
     143              80 :   if (NULL == channel->message_channel) {
     144               0 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
     145                 :                 "NaClSrpcChannelCtorHelper(channel=%p):"
     146                 :                 " NaClSrpcMessageChannelNew failed\n",
     147                 :                 (void*) channel);
     148               0 :     return 0;
     149                 :   }
     150              80 :   return 1;
     151                 : }
     152                 : 
     153              59 : static void NaClSrpcChannelDtorHelper(NaClSrpcChannel* channel) {
     154              59 :   NaClSrpcLog(1, "NaClSrpcChannelDtorHelper(channel=%p)\n", (void*) channel);
     155              59 :   channel->server_instance_data = NULL;
     156              59 :   NaClSrpcMessageChannelDelete(channel->message_channel);
     157              59 :   channel->message_channel = NULL;
     158              59 : }
     159                 : 
     160              55 : int NaClSrpcClientCtor(NaClSrpcChannel* channel, NaClSrpcImcDescType handle) {
     161              55 :   int return_value                = 0;
     162              55 :   NaClSrpcService* client_service = NULL;
     163              55 :   NaClSrpcLog(1,
     164                 :               "NaClSrpcClientCtor(channel=%p, handle=%p)\n",
     165                 :               (void*) channel,
     166                 :               (void*) handle);
     167              55 :   if (!NaClSrpcChannelCtorHelper(channel, handle)) {
     168               0 :     goto cleanup;
     169                 :   }
     170                 :   /* Do service discovery to speed method invocation. */
     171              55 :   client_service = BuildClientService(channel);
     172              50 :   if (NULL == client_service) {
     173               1 :     NaClSrpcLog(NACL_SRPC_LOG_ERROR,
     174                 :                 "NaClSrpcClientCtor(channel=%p):"
     175                 :                 " BuildClientService failed\n",
     176                 :                 (void*) channel);
     177               1 :     NaClSrpcChannelDtorHelper(channel);
     178               1 :     goto cleanup;
     179                 :   }
     180                 :   /* Channel takes ownership of client_service. */
     181              49 :   channel->client = client_service;
     182              49 :   client_service = NULL;
     183              49 :   return_value = 1;
     184                 :  cleanup:
     185              50 :   NaClSrpcServiceDtor(client_service);
     186              50 :   return return_value;
     187                 : }
     188                 : 
     189              25 : int NaClSrpcServerCtor(NaClSrpcChannel* channel,
     190                 :                        NaClSrpcImcDescType handle,
     191                 :                        NaClSrpcService* service,
     192                 :                        void* server_instance_data) {
     193              25 :   int return_value = 0;
     194              25 :   NaClSrpcLog(1,
     195                 :               "NaClSrpcServerCtor(channel=%p, handle=%p,"
     196                 :               " service=%p, server_instance_data=%p)\n",
     197                 :               (void*) channel,
     198                 :               (void*) handle,
     199                 :               (void*) service,
     200                 :               (void*) server_instance_data);
     201              25 :   if (!NaClSrpcChannelCtorHelper(channel, handle)) {
     202               0 :     goto cleanup;
     203                 :   }
     204                 :   /* Channel takes ownership of service. */
     205              25 :   channel->server = service;
     206                 :   /* Channel does not take ownership of server_instance_data. */
     207              25 :   channel->server_instance_data = server_instance_data;
     208              25 :   return_value = 1;
     209                 :  cleanup:
     210              25 :   return return_value;
     211                 : }
     212                 : 
     213              58 : void NaClSrpcDtor(NaClSrpcChannel* channel) {
     214              58 :   NaClSrpcLog(1,
     215                 :               "NaClSrpcDtor(channel=%p)\n",
     216                 :               (void*) channel);
     217              58 :   if (NULL == channel) {
     218              58 :     return;
     219                 :   }
     220              58 :   channel->server_instance_data = NULL;
     221              58 :   NaClSrpcServiceDtor(channel->client);
     222              58 :   free(channel->client);
     223              58 :   channel->client = NULL;
     224              58 :   NaClSrpcServiceDtor(channel->server);
     225              58 :   free(channel->server);
     226              58 :   channel->server = NULL;
     227                 :   /* Do the common part destruction. */
     228              58 :   NaClSrpcChannelDtorHelper(channel);
     229                 : }
     230                 : 
     231             654 : void NaClSrpcArgCtor(NaClSrpcArg* arg) {
     232             654 :   memset(arg, 0, sizeof *arg);
     233             654 : }

Generated by: LCOV version 1.7