LCOV - code coverage report
Current view: directory - src/trusted/sel_universal - pnacl_emu_stream.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 62 0 0.0 %
Date: 2014-06-18 Functions: 0 0 -

       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                 : #include <cstring>
       8                 : #include <string>
       9                 : #include <vector>
      10                 : 
      11                 : #include "native_client/src/include/nacl_scoped_ptr.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_time.h"
      14                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      15                 : 
      16                 : #include "native_client/src/trusted/sel_universal/parsing.h"
      17                 : #include "native_client/src/trusted/sel_universal/pnacl_emu_handler.h"
      18                 : #include "native_client/src/trusted/sel_universal/rpc_universal.h"
      19                 : 
      20                 : using std::string;
      21                 : using std::vector;
      22                 : 
      23                 : namespace {
      24                 : 
      25                 : int
      26               0 : SendDataChunk(NaClCommandLoop* ncl, nacl_abi_size_t size, const char *data) {
      27               0 :   const string signature = string("StreamChunk:C:");
      28               0 :   NaClSrpcArg in[1];
      29               0 :   NaClSrpcArg* inv[2];
      30               0 :   BuildArgVec(inv, in, 1);
      31               0 :   in[0].tag = NACL_SRPC_ARG_TYPE_CHAR_ARRAY;
      32               0 :   in[0].arrays.carr = static_cast<char*>(malloc(size));
      33               0 :   if (0 == in[0].arrays.carr) {
      34               0 :     NaClLog(LOG_ERROR, "allocation failed\n");
      35               0 :     FreeArrayArgs(inv);
      36               0 :     return -1;
      37                 :   }
      38               0 :   in[0].u.count = size;
      39               0 :   memcpy(in[0].arrays.carr, data, size);
      40                 : 
      41               0 :   NaClSrpcArg* outv[1];
      42               0 :   outv[0] = NULL;
      43               0 :   if (!ncl->InvokeNexeRpc(signature, inv, outv)) {
      44               0 :     NaClLog(LOG_ERROR, "StreamChunk failed\n");
      45               0 :     FreeArrayArgs(inv);
      46               0 :     return -1;
      47                 :   }
      48               0 :   return 0;
      49               0 : }
      50                 : 
      51                 : // Stream the file to the client with a series of StreamChunk RPCs.
      52                 : // Rate-limit the sending to bits_per_sec to emulate a download
      53               0 : bool PnaclStreamFile(NaClCommandLoop* ncl, FILE* input_file,
      54               0 :                             int chunk_size, int bits_per_sec) {
      55               0 :   nacl::scoped_array<char> data(new char[chunk_size]);
      56               0 :   NaClLog(LOG_INFO, "Streaming file at %d bps\n", bits_per_sec);
      57               0 :   uint64_t start_time = NaClGetTimeOfDayMicroseconds();
      58               0 :   size_t data_sent = 0;
      59               0 :   while (!feof(input_file) && !ferror(input_file)) {
      60               0 :     size_t data_read = fread(data.get(), 1, chunk_size, input_file);
      61               0 :     uint64_t cur_elapsed_us = NaClGetTimeOfDayMicroseconds() - start_time;
      62               0 :     uint64_t target_elapsed_us = static_cast<uint64_t>(data_sent + data_read)
      63                 :         * 8 * 1000000 / bits_per_sec;
      64               0 :     if (cur_elapsed_us < target_elapsed_us) {
      65               0 :       uint64_t sleep_us = target_elapsed_us - cur_elapsed_us;
      66               0 :       struct nacl_abi_timespec req;
      67               0 :       struct nacl_abi_timespec rem;
      68               0 :       req.tv_sec = sleep_us / 1000000;
      69               0 :       req.tv_nsec = sleep_us % 1000000 * 1000;
      70               0 :       int ret = NaClNanosleep(&req, &rem);
      71               0 :       if (ret == -1) {
      72               0 :         NaClLog(LOG_ERROR, "NaClNanosleep failed");
      73               0 :         return false;
      74                 :       }
      75               0 :     }
      76               0 :     if (SendDataChunk(ncl, static_cast<nacl_abi_size_t>(data_read),
      77               0 :                       data.get())) {
      78                 :       // If SendDataChunkFails, just return immediately, but don't fail.
      79                 :       // This will cause the final RPC to be run by the script to get the
      80                 :       // error string.
      81               0 :       NaClLog(LOG_ERROR, "stream_file: SendDataChunk failed, but returning"
      82                 :                          " without failing. Expect call to StreamEnd.");
      83               0 :       return true;
      84                 :     }
      85               0 :     data_sent += data_read;
      86               0 :   }
      87               0 :   return true;
      88               0 : }
      89                 : 
      90                 : }  // namespace
      91                 : 
      92               0 : bool HandlerPnaclFileStream(NaClCommandLoop* ncl,
      93               0 :                             const vector<string>& args) {
      94               0 :   if (args.size() != 4) {
      95               0 :     NaClLog(LOG_ERROR, "not enough args to file_stream\n");
      96               0 :     return false;
      97                 :   }
      98                 : 
      99               0 :   FILE* input_file = fopen(args[1].c_str(), "rb");
     100               0 :   if (NULL == input_file) {
     101               0 :     NaClLog(LOG_ERROR, "could not open input file %s\n", args[1].c_str());
     102               0 :     return false;
     103                 :   }
     104               0 :   return PnaclStreamFile(ncl, input_file, strtol(args[2].c_str(), 0, 0),
     105               0 :                          strtol(args[3].c_str(), 0, 0));
     106               0 : }

Generated by: LCOV version 1.7