<commit_before>/*
Copyright c1997-2006 <NAME>. All rights reserved.
This file is part of the Code Vault version 2.5.1
http://www.bombaydigital.com/
*/

/** @file */

#include "vthread.h"

#include <exception>
#include "vexception.h"
#include "vmanagementinterface.h"
#include "vlogger.h"
#include "vmutexlocker.h"

int VThread::smNumVThreads = 0;
int VThread::smNumThreadMains = 0;
int VThread::smNumVThreadsCreated = 0;
int VThread::smNumThreadMainsStarted = 0;
int VThread::smNumVThreadsDestructed = 0;
int VThread::smNumThreadMainsCompleted = 0;
VThreadActionListener* VThread::smActionListener = NULL;

// If we just declare this as an object, not a pointer, static initialization order
// problems can occur. This form ensures it is NULL until properly constructed.
static VMutex* gThreadStatsMutex = new VMutex();

VThread::VThread(const VString& name, bool deleteAtEnd, bool createDetached, VManagementInterface* manager) :
mIsDeleted(false),
mName(name),
mDeleteAtEnd(deleteAtEnd),
mCreateDetached(createDetached),
mManager(manager),
mThreadID((VThreadID_Type) -1),
mIsRunning(false)
    {
    VThread::_updateThreadStatistics(VThread::eCreated);

    VLOGGER_DEBUG(VString("VThread::VThread: constructed VThread '%s'.", name.chars()));
    }

VThread::~VThread()
    {
    // Detect repeat deletion bug. Can't refer to mName because it's been deleted.
    if (mIsDeleted)
        VLOGGER_ERROR(VString("Thread delete on already-deleted thread @0x%08X.", this));
    else
        VLOGGER_DEBUG(VString("VThread::~VThread: destructed VThread '%s'.", mName.chars()));

    mIsDeleted = true;
    mIsRunning = false;
    mThreadID = (VThreadID_Type) -1;

    // Prevent all exceptions from escaping destructor.
    try
        {
        VThread::_updateThreadStatistics(VThread::eDestroyed);
        }
    catch (...) {}
    }

void VThread::start()
    {
    if (mIsRunning)
        return;

    mIsRunning = true;
    
    if (!VThread::threadCreate(&mThreadID, mCreateDetached, VThread::threadMain, (void*) this))
        {
        mIsRunning = false;
        throw VException("VThread::start failed to start thread.");
        }
    }

void VThread::stop()
    {
    mIsRunning = false;
    }

VThreadID_Type VThread::threadID() const
    {
    return mThreadID;
    }

bool VThread::isRunning() const
    {
    return mIsRunning;
    }

bool VThread::join()
    {<commit_msg>Added ability to reference a user-defined stack crawl crash handling facility.<commit_after>/*
Copyright c1997-2006 <NAME>. All rights reserved.
This file is part of the Code Vault version 2.5.1
http://www.bombaydigital.com/
*/

/** @file */

#include "vthread.h"

#include <exception>
#include "vexception.h"
#include "vmanagementinterface.h"
#include "vlogger.h"
#include "vmutexlocker.h"

#ifdef VAULT_USER_STACKCRAWL_SUPPORT
#include "vstackcrawl_user.h"
#endif

int VThread::smNumVThreads = 0;
int VThread::smNumThreadMains = 0;
int VThread::smNumVThreadsCreated = 0;
int VThread::smNumThreadMainsStarted = 0;
int VThread::smNumVThreadsDestructed = 0;
int VThread::smNumThreadMainsCompleted = 0;
VThreadActionListener* VThread::smActionListener = NULL;

// If we just declare this as an object, not a pointer, static initialization order
// problems can occur. This form ensures it is NULL until properly constructed.
static VMutex* gThreadStatsMutex = new VMutex();

VThread::VThread(const VString& name, bool deleteAtEnd, bool createDetached, VManagementInterface* manager) :
mIsDeleted(false),
mName(name),
mDeleteAtEnd(deleteAtEnd),
mCreateDetached(createDetached),
mManager(manager),
mThreadID((VThreadID_Type) -1),
mIsRunning(false)
    {
    VThread::_updateThreadStatistics(VThread::eCreated);

    VLOGGER_DEBUG(VString("VThread::VThread: constructed VThread '%s'.", name.chars()));
    }

VThread::~VThread()
    {
    // Detect repeat deletion bug. Can't refer to mName because it's been deleted.
    if (mIsDeleted)
        VLOGGER_ERROR(VString("Thread delete on already-deleted thread @0x%08X.", this));
    else
        VLOGGER_DEBUG(VString("VThread::~VThread: destructed VThread '%s'.", mName.chars()));

    mIsDeleted = true;
    mIsRunning = false;
    mThreadID = (VThreadID_Type) -1;

    // Prevent all exceptions from escaping destructor.
    try
        {
        VThread::_updateThreadStatistics(VThread::eDestroyed);
        }
    catch (...) {}
    }

void VThread::start()
    {
    if (mIsRunning)
        return;

    mIsRunning = true;

#ifdef VAULT_USER_STACKCRAWL_SUPPORT
    if (!VThread::threadCreate(&mThreadID, mCreateDetached, VStackCrawl_userThreadMain, (void*) this))
#else    
    if (!VThread::threadCreate(&mThreadID, mCreateDetached, VThread::threadMain, (void*) this))
#endif
        {
        mIsRunning = false;
        throw VException("VThread::start failed to start thread.");
        }
    }

void VThread::stop()
    {
    mIsRunning = false;
    }

VThreadID_Type VThread::threadID() const
    {
    return mThreadID;
    }

bool VThread::isRunning() const
    {
    return mIsRunning;
    }

bool VThread::join()
    {
{'fraction_non_alphanumeric': 0.1198893936401343, 'fraction_numerical': 0.008690499703732965, 'mean_word_length': 3.974459724950884, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3920055', 'n_tokens_mistral': 1668, 'n_tokens_neox': 1640, 'n_words': 399}