blob: d9e12a596e10e9d8e93e0e7487d865074953fce8 [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#include "ThreadGroup.h"
#include "RecordTask.h"
#include "Session.h"
#include "Task.h"
#include "log.h"
namespace rr {
ThreadGroup::ThreadGroup(Session* session, ThreadGroup* parent,
pid_t tgid, pid_t tgid_own_namespace,
uint32_t serial)
: tgid(tgid),
tgid_own_namespace(tgid_own_namespace),
dumpable(true),
execed(false),
received_sigframe_SIGSEGV(false),
session_(session),
parent_(parent),
first_run_event_(0),
serial(serial) {
LOG(debug) << "creating new thread group " << tgid;
if (parent) {
parent->children_.insert(this);
}
session->on_create(this);
}
ThreadGroup::shr_ptr ThreadGroup::shared_from_this() {
return (*tasks.begin())->thread_group();
}
ThreadGroup::~ThreadGroup() {
if (session_) {
session_->on_destroy(this);
}
if (parent_) {
parent_->children_.erase(this);
}
for (ThreadGroup* tg : children()) {
tg->parent_ = nullptr;
// We don't fix the parenting during replay. Currently
// nothing depends on parenting during replay.
if (session_ && session_->is_recording()) {
auto it = tg->task_set().begin();
if (it != tg->task_set().end()) {
const RecordTask* rt = static_cast<const RecordTask*>(*it);
pid_t ppid = rt->get_parent_pid();
tg->parent_ = session_->find_thread_group(ppid);
if (tg->parent_) {
tg->parent_->children_.insert(tg);
}
}
}
}
}
} // namespace rr