void *add(void* arg)
{
  pthread_mutex_lock(&lock);
  //sleep(1);
  list.pushBack(int(arg));
  pthread_mutex_unlock(&lock);
}
void *read(void* arg)
{
  for(int i = 0; i < 100; i++)
  {
    std::cout << "Leggo il dato ";
    std::cout << list.popFront() << std::endl;
  }
 
  pthread_exit(0);
}
TEST(Concurrent, ConcurrentList) {
  const int numElem = 100;
  const int elemVal = 1;

  ConcurrentList<int> List;
  auto results = RaceTest<int*>(
    [&]() -> int* {
        for (int i = 0; i < numElem; i++)
          List.push_front(elemVal);
        return nullptr;
    }
  );

  size_t ListLen = std::distance(List.begin(), List.end());
  // Check that all of the values are initialized properly.
  for (auto A : List) {
    EXPECT_EQ(elemVal, A);
  }

  // Check that the length of the list is correct.
  EXPECT_EQ(ListLen, results.size() * numElem);
}
int main(int argc, char **argv) 
{
    std::cout << "Hello!" << std::endl;
    pthread_mutex_init(&lock, NULL);
    pthread_create(&thread1, NULL, read, NULL);
    for(int i = 0; i < 100; i++)
      pthread_create(&thread2, NULL, add, (void*)i);
    
    pthread_join(thread2, NULL);
    pthread_join(thread1, NULL);
    
    list.pushBack(5);
    list.pushBack(10);
    list.pushBack(4);
    list.pushBack(12);
    //Attenzione: pushFront
    list.pushFront(9);
    ConcurrentList<int>::cIterator iter;
    for(iter = list.begin(); iter != list.end(); iter++)
    {
      int i = *iter;
      std::cout << i << std::endl;
    }
    
    std::cout << "Eseguo la cancellazione singola (10)\n";
    
    iter = list.begin();
    iter++; iter++;
    iter = list.erase(iter);
    
    for(iter = list.begin(); iter != list.end(); iter++)
    {
      int i = *iter;
      std::cout << i << std::endl;
    }
    
    std::cout << "Eseguo le cancellazioni multiple (9 - 5) \n"; 
    iter = list.begin();
    iter++; iter++;
    iter = list.erase(list.begin(), iter);
    
    for(iter = list.begin(); iter != list.end(); iter++)
    {
      int i = *iter;
      std::cout << i << std::endl;
    }
    
    return 0;
}
TEST_CASE test_concurrent_list()
{
    stdString fred("fred");
    stdString freddy("freddy");
    stdString jane("jane");
    stdString janet("janet");
    stdString bob("bob");
    
    ConcurrentList<stdString> subscribers;
    TEST(subscribers.isEmpty() == true);
    TEST(subscribers.size()    == 0);
    TEST(subscribers.removeIfFound(&bob) == false);
    subscribers.add(&fred);
    TEST(subscribers.isEmpty() == false);
    TEST(subscribers.size()    == 1);
    subscribers.add(&freddy);
    TEST(subscribers.isEmpty() == false);
    TEST(subscribers.size()    == 2);
    subscribers.add(&jane);
    TEST(subscribers.isEmpty() == false);
    TEST(subscribers.size()    == 3);
    subscribers.add(&janet);
    TEST(subscribers.isEmpty() == false);
    TEST(subscribers.size()    == 4);
    
    TEST(subscribers.removeIfFound(&bob) == false);
    
    // This test assumes a certain order in which
    // elements are added to the list,
    // which could change with different implementations
    // of the ConcurrentList.
    
    COMMENT("Simple Iteration");
    ConcurrentListIterator<stdString> s(subscribers.iterator());
    TEST(*s.next() == "fred");
    TEST(*s.next() == "freddy");
    TEST(*s.next() == "jane");
    TEST(*s.next() == "janet");
    TEST(s.next() == 0);
    TEST(s.next() == 0);
    TEST(s.next() == 0);
    TEST(s.next() == 0);
        
    COMMENT("Iteration where 'fred' is removed while iterator is on it");
    // Start over: Position on first entry, "fred"
    s = subscribers.iterator();
    // Remove element, ...
    subscribers.remove(&fred);
    // but iterator was already on the element, so you still get it:
    TEST(*s.next() == "fred");
    TEST(*s.next() == "freddy");
    TEST(*s.next() == "jane");
    TEST(*s.next() == "janet");
    TEST(s.next() == 0);
    TEST(s.next() == 0);

    COMMENT("Iteration where 'fred' is gone, but 'bob' was added.");
    COMMENT("Then add 'fred' again while iterating.");
    subscribers.add(&bob);
    s = subscribers.iterator();
    TEST(*s.next() == "bob");
    TEST(*s.next() == "freddy");
    subscribers.add(&fred);
    TEST(*s.next() == "jane");
    TEST(*s.next() == "janet");
    TEST(*s.next() == "fred");
    TEST(s.next() == 0);
    TEST(s.next() == 0);
    
    TEST_OK;
}