/*
 * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: t-evthr-3.c,v 1.7 2005/09/23 18:05:41 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/heap.h"
#include "sm/test.h"
#include "sm/evthr.h"
#include "sm/io.h"
#include "sm/unixsock.h"
#include "sm/signal.h"

#include <stdio.h>

#define WHAT_TERM	0
#define WHAT_CONT	1

static int Verbose = 0;

struct t_ctx_S
{
	sm_evthr_ctx_P	 ctx;
	int		 fd;
	int		 what;
	int		 status;
	int		 called;
};
typedef struct t_ctx_S t_ctx_T, *t_ctx_P;

/*
**  FCT1 -- wait for USR1
*/

static sm_ret_T
fct1(sm_evthr_task_P tsk)
{
	t_ctx_P fctx;

	SM_ASSERT(tsk != NULL);
	SM_ASSERT(evthr_got_sg(tsk));
	fctx = (t_ctx_P) tsk->evthr_t_actx;
	fctx->called++;
	if (Verbose > 1)
		fprintf(stderr, "fct1: called %p, called=%d, loops=%d\n",
			tsk, fctx->called, fctx->status);
	if (fctx->called > fctx->status)
		return EVTHR_TERM|EVTHR_DEL;
	return EVTHR_WAITQ;
}

static void
testev(int what, int loops, int reps)
{
	sm_ret_T ret;
	sm_evthr_ctx_P evthr_ctx;
	sm_evthr_task_P	task3;
	t_ctx_T tctx3;
	struct timeval sleept;

	ret = thr_init();
	SM_TEST(sm_is_success(ret));
	sm_memzero(&sleept, sizeof(sleept));
	ret = evthr_init(&evthr_ctx, 1, 6, 10);
	SM_TEST(sm_is_success(ret));
	SM_TEST(evthr_ctx != NULL);

	tctx3.ctx = evthr_ctx;
	tctx3.fd = SIGUSR1;
	tctx3.what = what;
	tctx3.status = loops;
	tctx3.called = 0;
	ret = evthr_task_new(evthr_ctx, &task3, EVTHR_EV_SG, tctx3.fd,
			&sleept, fct1, (void *) &tctx3);
	SM_TEST(sm_is_success(ret));
	SM_TEST(task3 != NULL);

	ret = evthr_loop(evthr_ctx);
	SM_TEST(sm_is_success(ret));
	if (!sm_is_success(ret))
		fprintf(stderr, "evthr_loop()=%x\n", ret);

	/*
	**  we should "hold" the system before deleting tasks?
	**  deleting the tasks while they are still in use
	**  will break things.
	*/

	SM_TEST(tctx3.called > 0);
	if (reps > 0)
		SM_TEST(tctx3.called == reps);
	if (Verbose > 0)
	{
		fprintf(stderr, "fcts=%d\n", tctx3.called);
	}
	ret = evthr_stop(evthr_ctx);
	SM_TEST(sm_is_success(ret));
	if (!sm_is_success(ret))
		fprintf(stderr, "evthr_stop()=%x\n", ret);
	ret = thr_stop();
	SM_TEST(sm_is_success(ret));
}

int
main(int argc, char *argv[])
{
	int c, what, loops, reps;

	what = 1;
	loops = 16;
	reps = -1;
	while ((c = getopt(argc, argv, "l:r:w:V")) != -1)
	{
		switch (c)
		{
		  case 'l':
			loops = atoi(optarg);
			break;
		  case 'r':
			reps = atoi(optarg);
			break;
		  case 'w':
			what = atoi(optarg);
			break;
		  case 'V':
			Verbose++;
			break;
#if 0
		  default:
			usage(argv[0]);
			return(1);
#endif /* 0 */
		}
	}
	sm_test_begin(argc, argv, "test evthr signal");
	testev( what, loops, reps);
	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1