blob: afd9d15b80568267fae5b45f544e712d262cd7a9 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_BIN_TRACE_MANAGER_TRACE_SESSION_H_
#define GARNET_BIN_TRACE_MANAGER_TRACE_SESSION_H_
#include <fuchsia/tracing/provider/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/string.h>
#include <lib/fidl/cpp/vector.h>
#include <lib/fit/function.h>
#include <lib/zx/socket.h>
#include <lib/zx/time.h>
#include <lib/zx/vmo.h>
#include <iosfwd>
#include <list>
#include <vector>
#include "garnet/bin/trace_manager/trace_provider_bundle.h"
#include "garnet/bin/trace_manager/tracee.h"
#include "src/lib/fxl/memory/ref_counted.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace tracing {
namespace provider = ::fuchsia::tracing::provider;
// TraceSession keeps track of all TraceProvider instances that
// are active for a tracing session.
class TraceSession : public fxl::RefCountedThreadSafe<TraceSession> {
public:
enum class State { kReady, kStarted, kStopping, kStopped };
// Initializes a new instances that streams results
// to |destination|. Every provider active in this
// session is handed |categories| and a vmo of size
// |trace_buffer_size_megabytes| when started.
//
// |abort_handler| is invoked whenever the session encounters
// unrecoverable errors that render the session dead.
explicit TraceSession(zx::socket destination, std::vector<std::string> categories,
size_t trace_buffer_size_megabytes, provider::BufferingMode buffering_mode,
TraceProviderSpecMap&& provider_specs, fit::closure abort_handler);
// Frees all allocated resources and closes the outgoing
// connection.
~TraceSession();
const zx::socket& destination() const { return destination_; }
// For testing.
State state() const { return state_; }
// Invokes |callback| when all providers in this session have acknowledged
// the start request, or after |timeout| has elapsed.
void WaitForProvidersToStart(fit::closure callback, zx::duration timeout);
// Writes all applicable trace info records.
// These records are like a pre-amble to the trace, in particular they
// provide a record at the start of the trace that when written to a file
// can be used to identify the file as a Fuchsia Trace File.
void WriteTraceInfo();
// Starts |provider| and adds it to this session.
void AddProvider(TraceProviderBundle* provider);
// Stops |provider|, streaming out all of its trace records.
void RemoveDeadProvider(TraceProviderBundle* provider);
// Stops all providers that are part of this session, streams out
// all remaining trace records and finally invokes |done_callback|.
//
// If stopping providers takes longer than |timeout|, we forcefully
// shutdown operations and invoke |done_callback|.
void Stop(fit::closure done_callback, zx::duration timeout);
private:
friend std::ostream& operator<<(std::ostream& out, TraceSession::State state);
void OnProviderStarted(TraceProviderBundle* bundle);
void CheckAllProvidersStarted();
void NotifyStarted();
void FinishProvider(TraceProviderBundle* bundle);
void FinishSessionIfEmpty();
void FinishSessionDueToTimeout();
void SessionStartTimeout(async_dispatcher_t* dispatcher, async::TaskBase* task,
zx_status_t status);
void SessionFinalizeTimeout(async_dispatcher_t* dispatcher, async::TaskBase* task,
zx_status_t status);
void Abort();
TransferStatus WriteMagicNumberRecord();
void TransitionToState(State state);
State state_ = State::kReady;
zx::socket destination_;
fidl::VectorPtr<std::string> categories_;
size_t trace_buffer_size_megabytes_;
provider::BufferingMode buffering_mode_;
TraceProviderSpecMap provider_specs_;
std::list<std::unique_ptr<Tracee>> tracees_;
async::TaskMethod<TraceSession, &TraceSession::SessionStartTimeout> session_start_timeout_{this};
async::TaskMethod<TraceSession, &TraceSession::SessionFinalizeTimeout> session_finalize_timeout_{
this};
fit::closure start_callback_;
fit::closure done_callback_;
fit::closure abort_handler_;
fxl::WeakPtrFactory<TraceSession> weak_ptr_factory_;
TraceSession(const TraceSession&) = delete;
TraceSession(TraceSession&&) = delete;
TraceSession& operator=(const TraceSession&) = delete;
TraceSession& operator=(TraceSession&&) = delete;
};
std::ostream& operator<<(std::ostream& out, TraceSession::State state);
} // namespace tracing
#endif // GARNET_BIN_TRACE_MANAGER_TRACE_SESSION_H_