Commit bd4538cc authored by legoc's avatar legoc
Browse files

implemented connection handler

parent ab7ad18d
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_boost_date_time.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_DATE_TIME
#
# DESCRIPTION
#
# Test for Date_Time library from the Boost C++ libraries. The macro
# requires a preceding call to AX_BOOST_BASE. Further documentation is
# available at <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_DATE_TIME_LIB)
#
# And sets:
#
# HAVE_BOOST_DATE_TIME
#
# LICENSE
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
# Copyright (c) 2008 Michael Tindal
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 21
AC_DEFUN([AX_BOOST_DATE_TIME],
[
AC_ARG_WITH([boost-date-time],
AS_HELP_STRING([--with-boost-date-time@<:@=special-lib@:>@],
[use the Date_Time library from boost - it is possible to specify a certain library for the linker
e.g. --with-boost-date-time=boost_date_time-gcc-mt-d-1_33_1 ]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ax_boost_user_date_time_lib=""
else
want_boost="yes"
ax_boost_user_date_time_lib="$withval"
fi
],
[want_boost="yes"]
)
if test "x$want_boost" = "xyes"; then
AC_REQUIRE([AC_PROG_CC])
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_CACHE_CHECK(whether the Boost::Date_Time library is available,
ax_cv_boost_date_time,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/date_time/gregorian/gregorian_types.hpp>]],
[[using namespace boost::gregorian; date d(2002,Jan,10);
return 0;
]])],
ax_cv_boost_date_time=yes, ax_cv_boost_date_time=no)
AC_LANG_POP([C++])
])
if test "x$ax_cv_boost_date_time" = "xyes"; then
AC_DEFINE(HAVE_BOOST_DATE_TIME,,[define if the Boost::Date_Time library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
if test "x$ax_boost_user_date_time_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_date_time*.so* $BOOSTLIBDIR/libboost_date_time*.dylib* $BOOSTLIBDIR/libboost_date_time*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_date_time.*\)\.so.*$;\1;' -e 's;^lib\(boost_date_time.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_date_time.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break],
[link_date_time="no"])
done
if test "x$link_date_time" != "xyes"; then
for libextension in `ls $BOOSTLIBDIR/boost_date_time*.dll* $BOOSTLIBDIR/boost_date_time*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_date_time.*\)\.dll.*$;\1;' -e 's;^\(boost_date_time.*\)\.a.*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break],
[link_date_time="no"])
done
fi
else
for ax_lib in $ax_boost_user_date_time_lib boost_date_time-$ax_boost_user_date_time_lib; do
AC_CHECK_LIB($ax_lib, main,
[BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break],
[link_date_time="no"])
done
fi
if test "x$ax_lib" = "x"; then
AC_MSG_ERROR(Could not find a version of the library!)
fi
if test "x$link_date_time" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
fi
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "ConnectionHandlerSet.h"
#include "../Server.h"
using namespace std;
namespace cameo {
ConnectionHandlerSet::ConnectionHandlerSet(Server * server) : m_server(server) {
}
ConnectionHandlerSet::~ConnectionHandlerSet() {
stopThread();
}
void ConnectionHandlerSet::add(std::string const & name, ConnectionHandlerSet::FunctionType handler) {
boost::mutex::scoped_lock lock(m_mutex);
m_set[name] = handler;
}
bool ConnectionHandlerSet::remove(std::string const & name) {
boost::mutex::scoped_lock lock(m_mutex);
map<string, FunctionType>::iterator h = m_set.find(name);
if (h != m_set.end()) {
m_set.erase(h);
return true;
}
return false;
}
void ConnectionHandlerSet::apply(bool available) {
boost::mutex::scoped_lock lock(m_mutex);
for (map<string, FunctionType>::const_iterator h = m_set.begin(); h != m_set.end(); ++h) {
h->second(available);
}
}
void ConnectionHandlerSet::loop(int timeoutMs, int pollingTimeMs) {
// Loop until the condition is notified.
while (true) {
bool stopped = m_waitCondition.wait(pollingTimeMs);
if (stopped) {
return;
}
// Check the server.
bool available = (m_server->isAvailable(timeoutMs));
// Apply the handlers.
apply(available);
}
}
void ConnectionHandlerSet::startThread(int timeoutMs, int pollingTimeMs) {
// Stop the thread if it exists.
stopThread();
// Start the thread.
m_thread = auto_ptr<boost::thread>(new boost::thread(boost::bind(&ConnectionHandlerSet::loop, this, timeoutMs, pollingTimeMs)));
}
void ConnectionHandlerSet::stopThread() {
if (m_thread.get() != 0) {
m_waitCondition.notify();
m_thread->join();
}
}
}
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAMEO_CONNECTIONHANDLERSET_H_
#define CAMEO_CONNECTIONHANDLERSET_H_
#include "TimeCondition.h"
#include <boost/function.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <memory>
#include <string>
#include <map>
namespace cameo {
class Server;
/**
* Class containing a set of connection handler objects.
* It is protected with a mutex because the class must be thread-safe.
*/
class ConnectionHandlerSet {
public:
typedef boost::function<void (bool)> FunctionType;
ConnectionHandlerSet(Server * server);
~ConnectionHandlerSet();
void add(std::string const & name, FunctionType handler);
bool remove(std::string const & name);
void startThread(int timeoutMs, int pollingTimeMs);
void stopThread();
private:
void apply(bool available);
void loop(int timeoutMs, int pollingTimeMs);
Server * m_server;
TimeCondition m_waitCondition;
boost::mutex m_mutex;
std::map<std::string, FunctionType> m_set;
std::auto_ptr<boost::thread> m_thread;
};
}
#endif
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "TimeCondition.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
using namespace std;
namespace cameo {
TimeCondition::TimeCondition() :
m_notified(false) {
}
TimeCondition::~TimeCondition() {
}
bool TimeCondition::wait(long timeMs) {
boost::mutex::scoped_lock lock(m_conditionMutex);
if (!m_notified) {
boost::posix_time::time_duration duration = boost::posix_time::millisec(timeMs);
return m_condition.timed_wait(lock, duration);
}
// sure that notify occurred
return true;
}
void TimeCondition::notify() {
boost::mutex::scoped_lock lock(m_conditionMutex);
m_notified = true;
m_condition.notify_one();
}
}
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAMEO_TIMECONDITION_H_
#define CAMEO_TIMECONDITION_H_
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>
namespace cameo {
/**
* An "improved" "one-time notify" condition. If a notify occurs before the wait then
* the condition does NOT wait. Must not be used if the notify can occur for many times.
*/
class TimeCondition {
public:
/**
* Constructor.
*/
TimeCondition();
/**
* Destructor.
*/
~TimeCondition();
/**
* Waits for a notification. Returns false if the time has been reached. True if notified.
*/
bool wait(long timeMs);
/**
* Notifies the condition.
*/
void notify();
private:
boost::mutex m_conditionMutex;
boost::condition m_condition;
bool m_notified;
};
}
#endif
/*
* Copyright 2015 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>
#include <sstream>
#include "../cameo/cameo.h"
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
using namespace cameo;
struct ConnectionHandler {
void operator()(bool available) {
if (!available) {
application::This::cancelWaitings();
}
}
};
int main(int argc, char *argv[]) {
application::This::init(argc, argv);
// The start function must be called into a block to ensure the destructor of Instance is called before This::terminate()
{
Server server("tcp://localhost:8000");
server.addConnectionHandler("timeout", ConnectionHandler());
server.setTimeout(100, 100);
sleep(1);
//server.setTimeout(0);
cout << "reset timeout" << endl;
/*
if (server.isAvailable()) {
cout << "connected" << endl;
auto_ptr<application::Instance> resultApplication = server.start("test");
cout << "finished the application" << endl;
}
else {
cout << "not connected" << endl;
try {
auto_ptr<application::Instance> resultApplication = server.start("test");
}
catch (ConnectionTimeout const & e) {
cout << e.what() << endl;
}
cout << "started" << endl;
}*/
}
application::This::terminate();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment