Hello,

If I create a timer, start it, stop it and start it again
in the timer period, it will send multiple signals (one for each start).

To reproduce:
* build the attached program,
* run it
* point your browser on http://127.0.0.1:8080
* press the start and stop buttons several times (in 10 seconds),
  End with pressing the start button

Build environment:
* boost 1.34.1
* WT 2.2.3 (build single threaded)
* Ubuntu 8.10

Goetz

-- 
Goetz Babin-Ebell <[email protected]>
4G Systems GmbH & Co KG
#include "MyApplication.H"
#include "DebugHelper.H"
#include <Wt/WLabel> 
#include <Wt/WEnvironment>
#include <Wt/WPushButton>

MyApplication::MyApplication(const Wt::WEnvironment& env)
	: Wt::WApplication(env), m_timer(NULL)
	, m_lastTick(0), m_started(0), m_interval(10)
{
}

MyApplication::~MyApplication()
{
	if (m_timer) {
		try {
			m_timer->stop();
			delete m_timer;
		} catch (...) {
			 ;
		}
		m_timer = 0;
		m_started = 0;
		m_interval = 10;
	}
}

void MyApplication::initialize()
{
	logDebug << "app: INIT" << std::endl;  //lint !e534 !e1058
	Wt::WApplication::initialize();
	setTitle("TestApp");

	Wt::WPushButton *start = new Wt::WPushButton("START TIMER", root());
	start->clicked.connect(SLOT(this, MyApplication::startTimer));
	Wt::WPushButton *stop  = new Wt::WPushButton("STOP TIMER", root());
	stop->clicked.connect( SLOT(this, MyApplication::stopTimer ));
}

Wt::WApplication *MyApplication::create(const Wt::WEnvironment& env)
{
	logDebug << "create application..." << std::endl;

	MyApplication *app = new MyApplication(env);
	logInfo << "\nnew APPLICATION URL " << app->url() << std::endl;
	return app;
}

void MyApplication::startTimer() {
	if (!m_timer) {
		m_timer = new Wt::WTimer(this);
		(void)m_timer->timeout.connect(SLOT(this, MyApplication::tick));
		//m_timer->setObjectName(m_groups.getName());
		logInfo << "auto refresh timer "
			<< m_timer->id() /*<< " " << m_timer->objectName()*/
			<< " CREATE" <<  std::endl;
		m_timer->setInterval(m_interval * 1000);
		logInfo << "auto refresh timer "
			<< m_timer->id() /*<< " " << m_timer->objectName()*/
			<< " SET interval to " << m_interval << " seconds" << std::endl;
	}

	if (!m_timer->isActive()) {
		m_timer->start();
		m_started  = time(NULL);
		logDebug << "auto refresh timer "
			 << m_timer->id() /*<< " " << m_timer->objectName()*/
			 << " START with " << m_interval << " seconds" << std::endl;
	} else {
		logDebug << "auto refresh timer "
			 << m_timer->id() /*<< " " << m_timer->objectName()*/
			 << " CONTINUE with " << m_interval << " seconds" << std::endl;
	}
}

void MyApplication::stopTimer() {
	if (m_timer && m_timer->isActive()) {
		m_timer->stop();
		logDebug << "auto refresh timer "
			 << m_timer->id() /*<< " " << m_timer->objectName()*/
			 << " STOP" <<  std::endl;
	}
}
void MyApplication::tick() {
	time_t now = time(NULL);
	std::string outMsg("auto refresh timer ");
	outMsg += sender()->id();
	//outMsg += std::string(" ") +  sender()->objectName();
	outMsg += " TICK: ";
	outMsg += " started ";
	char temp[16];
	sprintf(temp,"%ld",now - m_started);
	outMsg += temp;
	outMsg += " seconds ago";
	if (m_lastTick) {
		sprintf(temp,"%ld",now - m_lastTick);
		outMsg += " last tick ";
		outMsg += temp;
		outMsg += " seconds ago";
	}
	logDebug << outMsg << std::endl;
	if (now - m_started < m_interval) {
		logErr   << "auto refresh timer " << sender()->id()
			 << " ignored because got bevore start time timed out" << std::endl;
		return;
	}
	if (m_lastTick && (now - m_lastTick < m_interval)) {
		logErr   << "auto refresh timer " << sender()->id()
			 << " ignored because got bevore last tick time timed out" << std::endl;
		return;
	}
	m_lastTick = now;
}
#ifndef MYAPPLICATION__H__
#define MYAPPLICATION__H__

#include <set>
#include <map>

#include <Wt/WApplication>
#include <Wt/WTimer>

class MyApplication : public Wt::WApplication
{
public:
	static Wt::WApplication *create(const Wt::WEnvironment& env);

	MyApplication(const Wt::WEnvironment& env);
	~MyApplication();

	virtual void initialize();

	void startTimer();
	void stopTimer();
	void tick();
protected:
	Wt::WTimer  *m_timer;
	time_t       m_lastTick;
	time_t       m_started;
	int          m_interval;
};

#endif /* MYAPPLICATION__H__ */
/**
 * @file    main.C
 * @author  Patrick Fischer <[email protected]>
 * @date    Tue Jul 10 09:41:32 2007
 *
 * @brief  Web Manager which create and manages the webinterface based on ConfigItems.
 *
 *
 */

/*
 * (c) COPYRIGHT 2007 by 4G Systems GmbH Germany
 * All rights reserved.
 */

#include <sstream>
#include <signal.h>

#include "MyApplication.H"
#include "DebugHelper.H"
#include <Wt/WServer>

typedef std::map<std::string,Wt::ApplicationCreator> ApplicationCreatorMap;

#if 1
static Wt::WServer *the_server = NULL;

static int MyWRun(int argc, char** argv,
		  const ApplicationCreatorMap &createApplicationMap,
		  Wt::ApplicationCreator createApplication = 0)
{
	try {
		Wt::WServer server(argv[0]);
		the_server = &server;
		try {
			server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
			ApplicationCreatorMap::const_iterator iter;
			for (iter = createApplicationMap.begin();
			     iter != createApplicationMap.end(); ++iter) {
				server.addEntryPoint(Wt::WServer::Application, iter->second, iter->first);
				logDebug << "add entry point for " << iter->first << std::endl;
			}
			if (createApplication || createApplicationMap.empty())
				server.addEntryPoint(Wt::WServer::Application, createApplication);
			if (server.start()) {
				logDebug << "Wt::WServer started..." << std::endl;
				// Wait for signal indicating time to shut down.
				sigset_t wait_mask;
				sigemptyset(&wait_mask);
				sigaddset(&wait_mask, SIGINT);
				sigaddset(&wait_mask, SIGQUIT);
				sigaddset(&wait_mask, SIGTERM);
				//sigaddset(&wait_mask, SIGCHLD);
				pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
				int sig = 0;
				//sigdelset(&wait_mask, SIGCHLD);

				int err;
				do {
					err = sigwait(&wait_mask, &sig);
				} while (err != 0);

				logInfo << "Shutdown (signal = " << sig << ")" << std::endl;
				server.stop();
			} else {
				logErr << "starting server failed..." << std::endl;
			}

			return 0;
		} catch (std::exception& e) {
			logErr << "failed to start server: " << e.what() << std::endl;
			return 1;
		}
	} catch (std::exception& e) {
		logErr << "exception: " << e.what() << "\n";
		return 1;
	}
}
#define WRUN(argc,argv,crMap,crAp) MyWRun(argc, argv, crMap, crAp);
#else
#define WRUN(argc,argv,crMap,crAp) Wt::WRun(argc, argv, crMap, crAp);
#endif

// you MUST increase this if you add more WT options...
#define MAX_WT_PASSED_OPTIONS 27
//lint -save -e818
int main (int argc, char *argv[])
{
	//lint -restore

	logInfo << "starting" << std::endl;

	const char *argvInt[MAX_WT_PASSED_OPTIONS];
	int         argcInt        = 0;
	argvInt[argcInt++]         = argv[0];

	argvInt[argcInt++] = "--pid-file";
	argvInt[argcInt++] = "./wthttpd.pid";

	argvInt[argcInt++] = "--docroot";
	argvInt[argcInt++] = "./";

	argvInt[argcInt++] = "--no-compression";

	argvInt[argcInt++] = "--deploy-path";
	argvInt[argcInt++] = "/";

	argvInt[argcInt++] = "--http-address";
	argvInt[argcInt++] = "0.0.0.0";

	argvInt[argcInt++] = "--http-port";
	argvInt[argcInt++] = "8080";

	ApplicationCreatorMap creatorMap;
	creatorMap.insert(ApplicationCreatorMap::value_type("/",          MyApplication::create));
	creatorMap.insert(ApplicationCreatorMap::value_type("index.html", MyApplication::create));

	int ret = WRUN(argcInt, (char**)argvInt, creatorMap, MyApplication::create);

	logInfo << "normal program end..." << ret << std::endl;
	return ret;

} //lint !e818
#ifndef DEBUGHELPER_H
#define DEBUGHELPER_H

#include <iostream>
#define logDebug std::cout << "DEBUG: "
#define logInfo  std::cout << "INFO:  "
#define logErr   std::cout << "ERR:   "

#endif // DEBUGHELPER_H
------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
witty-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to