<commit_before>#include <gtest/gtest.h>
#include <cassert>
#include <unistd.h>

#include "../../cvmfs/util.h"
#include "../../cvmfs/util_concurrency.h"


struct thread_args {
  int                    state;
  SynchronizingIntCounter *counter;
};


class T_SynchronizingCounter : public ::testing::Test {
 public:
  T_SynchronizingCounter() :
    threads_(NULL), states_(NULL), n_threads_(0) {}
  virtual ~T_SynchronizingCounter() {
    Clear();
  }

 protected:
  void StartThreads(const unsigned int     number_of_threads,
                    SynchronizingIntCounter &counter_to_test,
                    void *(*thread_function)(void*)) {
    n_threads_ = number_of_threads;
    threads_   = new pthread_t[n_threads_];
    states_    = new thread_args[n_threads_];

    for (unsigned int i = 0; i < n_threads_; ++i) {
      states_[i].state   = 0;
      states_[i].counter = &counter_to_test;
      const int r = pthread_create(&threads_[i], NULL,
                                   thread_function, &states_[i]);
      ASSERT_EQ (0, r) << "Failed to spawn thread";
    }
  }

  void CheckStateValues(const int expected_value,
                        const std::string &error_message = "") {
    for (unsigned int i = 0; i < n_threads_; ++i) {
      EXPECT_EQ (expected_value, states_[i].state) << error_message;
    }
  }

  void JoinThreads() {
    for (unsigned int i = 0; i < n_threads_; ++i) {
      const int killed = pthread_kill(threads_[i], 0);
      EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
      if (killed == ESRCH) {
        pthread_cancel(threads_[i]);
      }
    }

    Clear();
  }

  void Clear() {
    if (threads_ != NULL) {
      delete[] threads_;
      threads_ = NULL;
    }

    if (states_ != NULL) {
      delete[] states_;
      states_ = NULL;<commit_msg>FIX: proper thread destruction in SynchronizingCounter test<commit_after>#include <gtest/gtest.h>
#include <cassert>
#include <unistd.h>

#include "../../cvmfs/util.h"
#include "../../cvmfs/util_concurrency.h"


struct thread_args {
  int                    state;
  SynchronizingIntCounter *counter;
};


class T_SynchronizingCounter : public ::testing::Test {
 public:
  T_SynchronizingCounter() :
    threads_(NULL), states_(NULL), n_threads_(0) {}
  virtual ~T_SynchronizingCounter() {
    Clear();
  }

 protected:
  void StartThreads(const unsigned int     number_of_threads,
                    SynchronizingIntCounter &counter_to_test,
                    void *(*thread_function)(void*)) {
    n_threads_ = number_of_threads;
    threads_   = new pthread_t[n_threads_];
    states_    = new thread_args[n_threads_];

    for (unsigned int i = 0; i < n_threads_; ++i) {
      states_[i].state   = 0;
      states_[i].counter = &counter_to_test;
      const int r = pthread_create(&threads_[i], NULL,
                                   thread_function, &states_[i]);
      ASSERT_EQ (0, r) << "Failed to spawn thread";
    }
  }

  void CheckStateValues(const int expected_value,
                        const std::string &error_message = "") {
    for (unsigned int i = 0; i < n_threads_; ++i) {
      EXPECT_EQ (expected_value, states_[i].state) << error_message;
    }
  }

  void JoinThreads() {
    for (unsigned int i = 0; i < n_threads_; ++i) {
      const int killed = pthread_kill(threads_[i], 0);
      EXPECT_EQ (ESRCH, killed) << "Thread did not exit properly";
      if (killed != ESRCH) {
        pthread_cancel(threads_[i]);
      } else {
        pthread_join(threads_[i], NULL);
      }
    }

    Clear();
  }

  void Clear() {
    if (threads_ != NULL) {
      delete[] threads_;
      threads_ = NULL;
    }

    if (states_ != NULL) {
      delete[] states_;
      states_ = NULL;
{'fraction_non_alphanumeric': 0.1289714593430264, 'fraction_numerical': 0.003769520732364028, 'mean_word_length': 2.4981167608286254, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3942095', 'n_tokens_mistral': 1215, 'n_tokens_neox': 1181, 'n_words': 278}