Coverage for /Syzygy/trace/service/service.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
95.7%22230.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // This file declares the trace::service::Service class which implements
  16    :  // the call trace service RPC interface.
  17    :  
  18    :  #ifndef SYZYGY_TRACE_SERVICE_SERVICE_H_
  19    :  #define SYZYGY_TRACE_SERVICE_SERVICE_H_
  20    :  
  21    :  #include <map>
  22    :  
  23    :  #include "base/files/file_path.h"
  24    :  #include "base/memory/ref_counted.h"
  25    :  #include "base/process/process.h"
  26    :  #include "base/strings/string_piece.h"
  27    :  #include "base/synchronization/condition_variable.h"
  28    :  #include "base/threading/platform_thread.h"
  29    :  #include "base/threading/thread.h"
  30    :  #include "syzygy/trace/rpc/call_trace_rpc.h"
  31    :  
  32    :  namespace trace {
  33    :  namespace service {
  34    :  
  35    :  // Forward declarations.
  36    :  class BufferConsumerFactory;
  37    :  class Session;
  38    :  
  39    :  // Implements the CallTraceService interface (see "call_trace_rpc.idl".
  40    :  // For the most basic usage:
  41    :  //
  42    :  //   trace::service::Service::Instance().Start(false);
  43    :  //
  44    :  // This will access and launch a static instance of the service using a
  45    :  // default configuration. Specifying false, as in the above example,
  46    :  // will cause the call to be blocking; the call will not return until
  47    :  // the service is shutdown via the RequestShutdown() method. Specifying
  48    :  // true for the parameter to Start() will cause the Start() method to
  49    :  // return immediately, running the service in the background.
  50    :  //
  51    :  // Some mechanism to trigger a call to RequestShutdown() should be
  52    :  // provided to the operator of the service; for example, a signal handler
  53    :  // on SIGINT and/or SIGTERM, an event listening listening for a shutdown
  54    :  // Message, an IO loop waiting on a socket or Event, etc. The service
  55    :  // can also stopped remotely via an RPC call to CallTraceControl::Stop().
  56    :  class Service {
  57    :   public:
  58    :    typedef base::ProcessId ProcessId;
  59    :  
  60    :    // Flag passed to CommitAndExchangeBuffer() to determine whether or
  61    :    // not a fresh buffer should be returned to the client.
  62    :    enum ExchangeFlag {
  63    :      DO_NOT_PERFORM_EXCHANGE,
  64    :      PERFORM_EXCHANGE
  65    :    };
  66    :  
  67    :    // Construct a new call trace Service instance. The service will use the
  68    :    // given @p factory to construct buffer consumers for new sessions. The
  69    :    // service instance does NOT take ownership of the @p factory, which must
  70    :    // exist at least until the service instance is destroyed.
  71    :    explicit Service(BufferConsumerFactory* factory);
  72    :    ~Service();
  73    :  
  74    :    // The default number of buffers to allocate when expanding the buffer
  75    :    // pool allocated for a given client session.
  76    :    static const size_t kDefaultNumIncrementalBuffers;
  77    :  
  78    :    // The default size (in bytes) for each call trace buffer.
  79    :    static const size_t kDefaultBufferSize;
  80    :  
  81    :    // The default maximum number of buffers pending write that a session should
  82    :    // allow before beginning to force writes.
  83    :    static const size_t kDefaultMaxBuffersPendingWrite;
  84    :  
  85    :    // Set the id for this instance.
  86  E :    void set_instance_id(const base::StringPiece16& id) {
  87  E :      DCHECK(!is_running());
  88  E :      instance_id_.assign(id.begin(), id.end());
  89  E :    }
  90    :  
  91    :    // Set the trace flags that get communicated to clients on session creation.
  92    :    // The flags value should be bitmask composed of the values from the
  93    :    // TraceEventType enumeration (see call_trace_defs.h).
  94    :    //
  95    :    // @note TRACE_FLAG_BATCH_ENTER is mutually exclusive with all other flags.
  96    :    //     If TRACE_FLAG_BATCH_ENTER is set, all other flags will be ignored.
  97  i :    void set_flags(uint32_t flags) { flags_ = flags; }
  98    :  
  99    :    // Set the number of buffers by which to grow a sessions
 100    :    // buffer pool.
 101  E :    void set_num_incremental_buffers(size_t n) {
 102  E :      num_incremental_buffers_ = n;
 103  E :    }
 104    :  
 105    :    // Set the number of bytes comprising each buffer in a
 106    :    // sessions buffer pool.
 107  E :    void set_buffer_size_in_bytes(size_t n) {
 108  E :      buffer_size_in_bytes_ = n;
 109  E :    }
 110    :  
 111    :    // Sets the maximum number of buffers pending write that a session should
 112    :    // allow before starting to force buffer writes.
 113    :    // @param n the max number of buffers pending write to allow.
 114  E :    void set_max_buffers_pending_write(size_t n) {
 115  E :      DCHECK_LT(0u, n);
 116  E :      max_buffers_pending_write_ = n;
 117  E :    }
 118    :  
 119    :    // @returns the number of new buffers to be created per allocation.
 120  E :    size_t num_incremental_buffers() const { return num_incremental_buffers_; }
 121    :  
 122    :    // @returns the size (in bytes) of new buffers to be allocated.
 123  E :    size_t buffer_size_in_bytes() const { return buffer_size_in_bytes_; }
 124    :  
 125    :    // @returns the maximum number of buffers that sessions should allow to be
 126    :    //     pending writes prior to starting to force them.
 127  E :    size_t max_buffers_pending_write() const {
 128  E :      return max_buffers_pending_write_;
 129  E :    }
 130    :  
 131    :    // Returns true if any of the service's subsystems are running.
 132  E :    bool is_running() const {
 133  E :      return rpc_is_running_ || num_active_sessions_ > 0;
 134  E :    }
 135    :  
 136    :    // Begin accepting and handling RPC invocations. This method is not
 137    :    // generally callable by clients of the service; it may only be called
 138    :    // by the thread which created the service.
 139    :    //
 140    :    // The request handlers will be run on a thread pool owned by the RPC
 141    :    // runtime. If the non_blocking parameter is true, the call to Start()
 142    :    // will return immediately, allowing the owning thread to perform other
 143    :    // work while the service runs in the background. If non_blocking is
 144    :    // false, then the call to Start() will only return when the service
 145    :    // receives a shutdown request (via the RequestShutdown() method).
 146    :    //
 147    :    // Following the receipt of a shutdown request, it is the responsibility of
 148    :    // the thread which owns the service to call Stop() on the service, which
 149    :    // will take care of concluding any in-flight requests and flushing all
 150    :    // outstanding call trace buffers to disk.
 151    :    bool Start(bool non_blocking);
 152    :  
 153    :    // Completely shutdown the service. This method is not generally callable
 154    :    // by clients of the service; it may only be called by the thread which
 155    :    // created, and subsequently started, the service.
 156    :    //
 157    :    // Following the receipt of a shutdown request, it is the responsibility of
 158    :    // the thread which owns the service to call Stop() on the service, which
 159    :    // will take care of concluding any in-flight requests and flushing all
 160    :    // outstanding call trace buffers to disk.
 161    :    //
 162    :    // This is a blocking call, it will return after all outstanding requests
 163    :    // have been handled, all call trace buffers have been flushed, all
 164    :    // sessions have been closed, and all session resources deallocated.
 165    :    bool Stop();
 166    :  
 167    :    // RPC implementation of CallTraceControl::Stop().
 168    :    // See call_trace_rpc.idl for further info.
 169    :    bool RequestShutdown();
 170    :  
 171    :    // RPC implementation of CallTraceService::CreateSession().
 172    :    // See call_trace_rpc.idl for further info.
 173    :    bool CreateSession(handle_t binding,
 174    :                       SessionHandle* session_handle,
 175    :                       CallTraceBuffer* call_trace_buffer,
 176    :                       unsigned long* flags);
 177    :  
 178    :    // RPC implementation of CallTraceService::AllocateBuffer().
 179    :    // See call_trace_rpc.idl for further info.
 180    :    bool AllocateBuffer(SessionHandle session_handle,
 181    :                        CallTraceBuffer* call_trace_buffer);
 182    :  
 183    :    // RPC implementation of CallTraceService::AllocateLargeBuffer().
 184    :    // See call_trace_rpc.idl for further info.
 185    :    bool AllocateLargeBuffer(SessionHandle session_handle,
 186    :                             size_t minimum_size,
 187    :                             CallTraceBuffer* call_trace_buffer);
 188    :  
 189    :    // RPC implementation of both CallTraceService::ExchangeBuffer()
 190    :    // and CallTraceService::ReturnBuffer(). See call_trace_rpc.idl
 191    :    // for further info.
 192    :    bool CommitAndExchangeBuffer(SessionHandle session_handle,
 193    :                                 CallTraceBuffer* call_trace_buffer,
 194    :                                 ExchangeFlag perform_exchange);
 195    :  
 196    :    // RPC implementation of CallTraceService::CloseSession().
 197    :    // See call_trace_rpc.idl for further info.
 198    :    bool CloseSession(SessionHandle* session_handle);
 199    :  
 200    :    // Decrement the active session count.
 201    :    // @see num_active_sessions_
 202    :    void RemoveOneActiveSession();
 203    :  
 204    :    // Increment the active session count.
 205    :    // @see num_active_sessions_.
 206    :    void AddOneActiveSession();
 207    :  
 208    :   // These are protected for unittesting.
 209    :   protected:
 210    :  
 211    :    // @name RPC Server Management Functions.
 212    :    // These functions, unless otherwise noted, are single threaded and must
 213    :    // all be called from the thread that created this instance.
 214    :    // @{
 215    :    bool OpenServiceEvent();
 216    :    bool AcquireServiceMutex();
 217    :    void ReleaseServiceMutex();
 218    :    bool InitializeRpc();
 219    :    bool RunRPC(bool non_blocking);
 220    :  
 221    :    // This function is thread-safe.
 222    :    void StopRpc();
 223    :    void CleanupRpc();
 224    :    // @}
 225    :  
 226    :    // Creates a new session, returning true on success. On failure, the value
 227    :    // of *session will be NULL; otherwise it will contain a Session reference.
 228    :    bool GetNewSession(ProcessId client_process_id,
 229    :                       scoped_refptr<Session>* session);
 230    :  
 231    :    // Looks up an existing session, returning true on success. On failure,
 232    :    // the value of *session will be NULL; otherwise it will contain a
 233    :    // Session reference.
 234    :    bool GetExistingSession(SessionHandle session_handle,
 235    :                            scoped_refptr<Session>* session);
 236    :    // Looks up an existing session, returning true on success. On failure,
 237    :    // the value of *session will be NULL; otherwise it will contain a
 238    :    // Session reference.
 239    :    bool GetExistingSessionUnlocked(SessionHandle session_handle,
 240    :                                    scoped_refptr<Session>* session);
 241    :  
 242    :    // Closes all open sessions. This call blocks until all sessions have been
 243    :    // shutdown and have finished flushing their buffers.
 244    :    bool CloseAllOpenSessions();
 245    :  
 246    :    // Session factory. This is virtual for testing purposes.
 247    :    virtual Session* CreateSession();
 248    :  
 249    :    // Protects concurrent access to the internals, except for write-queue
 250    :    // related internals.
 251    :    base::Lock lock_;
 252    :  
 253    :    // The collection of open trace sessions. This is the collection of sessions
 254    :    // for which the service is currently accepting requests. Once a session is
 255    :    // closed, it is removed from this collection, but may still be active for
 256    :    // some time as it's trace buffers are consumed. See num_active_sessions_.
 257    :    typedef std::map<ProcessId, scoped_refptr<Session>> SessionMap;
 258    :    SessionMap sessions_;  // Under lock_.
 259    :  
 260    :    // A count of the number of active sessions currently managed by this service.
 261    :    // This includes both open sessions and closed sessions which have not yet
 262    :    // finished flushing their buffers.
 263    :    size_t num_active_sessions_;  // Under lock_.
 264    :  
 265    :    // The instance id to use when running this service instance.
 266    :    std::wstring instance_id_;
 267    :  
 268    :    // The number of buffers to allocate with each increment.
 269    :    size_t num_incremental_buffers_;
 270    :  
 271    :    // The number of bytes in each buffer.
 272    :    size_t buffer_size_in_bytes_;
 273    :  
 274    :    // The maximum number of buffers that a session should have pending write.
 275    :    size_t max_buffers_pending_write_;
 276    :  
 277    :    // Handle to the thread that owns/created this call trace service instance.
 278    :    base::PlatformThreadId owner_thread_;
 279    :  
 280    :    // The source factory for buffer consumer objects.
 281    :    BufferConsumerFactory* buffer_consumer_factory_;
 282    :  
 283    :    // Used to wait for all sessions to be closed on service shutdown.
 284    :    base::ConditionVariable a_session_has_closed_;  // Under lock_.
 285    :  
 286    :    // Used to detect whether multiple instances of the service are running
 287    :    // against the service endpoint.
 288    :    base::win::ScopedHandle service_mutex_;
 289    :  
 290    :    // Signaled once the service has successfully initialized.
 291    :    base::win::ScopedHandle service_event_;
 292    :  
 293    :    // Flags denoting the state of the RPC server.
 294    :    bool rpc_is_initialized_;
 295    :    // TODO(rogerm): Access to this flag is inconsistent, but it seems the
 296    :    //    transition from true to false will always take place under lock_.
 297    :    bool rpc_is_running_;  // Under lock_.
 298    :    bool rpc_is_non_blocking_;
 299    :  
 300    :    // Flags informing the client of what trace events the service would like
 301    :    // to receive.
 302    :    uint32_t flags_;
 303    :  
 304    :   private:
 305    :    DISALLOW_COPY_AND_ASSIGN(Service);
 306    :  };
 307    :  
 308    :  }  // namespace service
 309    :  }  // namespace trace
 310    :  
 311    :  #endif  // SYZYGY_TRACE_SERVICE_SERVICE_H_

Coverage information generated Fri Jul 29 11:00:21 2016.