/*
 *	Thread test program
 *	by Lee Kindness.
 */
#include <stdint.h>
#include <stdlib.h>
#include "ecpg_config.h"

#ifndef ENABLE_THREAD_SAFETY
int
main(void)
{
	printf("No threading enabled.\n");
	return 0;
}
#else
#ifndef WIN32
#include <pthread.h>
#else
#include <windows.h>
#include <locale.h>
#endif

exec sql include ../regression;

void *test_thread(void *arg);

int nthreads   = 10;
int iterations = 20;

int main()
{
#ifndef WIN32
  pthread_t *threads;
#else
  HANDLE *threads;
#endif
  intptr_t n;
  EXEC SQL BEGIN DECLARE SECTION;
  int l_rows;
  EXEC SQL END DECLARE SECTION;

 /* Do not switch on debug output for regression tests. The threads get executed in
  * more or less random order */
 /* ECPGdebug(1, stderr); */

  /* setup test_thread table */
  EXEC SQL CONNECT TO REGRESSDB1;
  EXEC SQL DROP TABLE test_thread; /* DROP might fail */
  EXEC SQL COMMIT;
  EXEC SQL CREATE TABLE
    test_thread(tstamp    TIMESTAMP NOT NULL DEFAULT CAST(timeofday() AS TIMESTAMP),
		thread    TEXT      NOT NULL,
		iteration INTEGER   NOT NULL,
		PRIMARY KEY(thread, iteration));
  EXEC SQL COMMIT;
  EXEC SQL DISCONNECT;

  /* create, and start, threads */
  threads = calloc(nthreads, sizeof(threads[0]));
  if( threads == NULL )
    {
      fprintf(stderr, "Cannot alloc memory\n");
      return 1;
    }
  for( n = 0; n < nthreads; n++ )
    {
#ifndef WIN32
      pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
#else
      threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n+1), 0, NULL);
#endif
    }

  /* wait for thread completion */
#ifndef WIN32
  for( n = 0; n < nthreads; n++ )
    {
      pthread_join(threads[n], NULL);
    }
#else
  WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
#endif
  free(threads);

  /* and check results */
  EXEC SQL CONNECT TO REGRESSDB1;
  EXEC SQL SELECT COUNT(*) INTO :l_rows FROM test_thread;
  EXEC SQL COMMIT;
  EXEC SQL DISCONNECT;
  if( l_rows == (nthreads * iterations) )
    printf("Success.\n");
  else
    printf("ERROR: Failure - expecting %d rows, got %d.\n", nthreads * iterations, l_rows);

  return 0;
}

void *test_thread(void *arg)
{
  long threadnum = (intptr_t) arg;

  EXEC SQL BEGIN DECLARE SECTION;
  int  l_i;
  char l_connection[128];
  EXEC SQL END DECLARE SECTION;

  /* build up connection name, and connect to database */
#ifndef _MSC_VER
  snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
#else
  _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
#endif
  EXEC SQL WHENEVER sqlerror sqlprint;
  EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection;
  if( sqlca.sqlcode != 0 )
    {
      printf("%s: ERROR: cannot connect to database!\n", l_connection);
      return NULL;
    }
  EXEC SQL BEGIN;

  /* insert into test_thread table */
  for( l_i = 1; l_i <= iterations; l_i++ )
    {
      EXEC SQL INSERT INTO test_thread(thread, iteration) VALUES(:l_connection, :l_i);
      if( sqlca.sqlcode != 0 )
	printf("%s: ERROR: insert failed!\n", l_connection);
    }

  /* all done */
  EXEC SQL COMMIT;
  EXEC SQL DISCONNECT :l_connection;
  return NULL;
}
#endif /* ENABLE_THREAD_SAFETY */
