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