blob: 0091295c1205ac17b77f92b0a7940a3aafe4fe58 [file] [log] [blame] [edit]
// 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 <functional>
#include <iosfwd>
#include <list>
#include <vector>
#include <fuchsia/tracelink/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/zx/socket.h>
#include <lib/zx/time.h>
#include <lib/zx/vmo.h>
#include "garnet/bin/trace_manager/trace_provider_bundle.h"
#include "garnet/bin/trace_manager/tracee.h"
#include "lib/fidl/cpp/string.h"
#include "lib/fidl/cpp/vector.h"
#include "lib/fxl/functional/closure.h"
#include "lib/fxl/macros.h"
#include "lib/fxl/memory/ref_counted.h"
#include "lib/fxl/memory/ref_ptr.h"
#include "lib/fxl/memory/weak_ptr.h"
namespace tracing {
// TraceSession keeps track of all TraceProvider instances that
// are active for a tracing session.
class TraceSession : public fxl::RefCountedThreadSafe<TraceSession> {
public:
// 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| when started.
//
// |abort_handler| is invoked whenever the session encounters
// unrecoverable errors that render the session dead.
explicit TraceSession(zx::socket destination,
fidl::VectorPtr<fidl::StringPtr> categories,
size_t trace_buffer_size, fxl::Closure abort_handler);
// Frees all allocated resources and closes the outgoing
// connection.
~TraceSession();
// Invokes |callback| when all providers in this session have acknowledged
// the start request, or after |timeout| has elapsed.
void WaitForProvidersToStart(fxl::Closure callback, zx::duration timeout);
// 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(fxl::Closure done_callback, zx::duration timeout);
private:
enum class State { kReady, kStarted, kStopping, kStopped };
friend std::ostream& operator<<(std::ostream& out, TraceSession::State state);
void NotifyStarted();
void Abort();
void CheckAllProvidersStarted();
void FinishProvider(TraceProviderBundle* bundle);
void FinishSessionIfEmpty();
void FinishSessionDueToTimeout();
void TransitionToState(State state);
void SessionStartTimeout(async_t* async, async::TaskBase* task,
zx_status_t status);
void SessionFinalizeTimeout(async_t* async, async::TaskBase* task,
zx_status_t status);
State state_ = State::kReady;
zx::socket destination_;
fidl::VectorPtr<fidl::StringPtr> categories_;
size_t trace_buffer_size_;
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};
fxl::Closure start_callback_;
fxl::Closure done_callback_;
fxl::Closure abort_handler_;
fxl::WeakPtrFactory<TraceSession> weak_ptr_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(TraceSession);
};
std::ostream& operator<<(std::ostream& out, TraceSession::State state);
} // namespace tracing
#endif // GARNET_BIN_TRACE_MANAGER_TRACE_SESSION_H_