-Reinhard Pfau <reinhard.pfau@intra2net.com>
+Authors of libasyncio:
+======================
+
+Reinhard Pfau <reinhard.pfau@intra2net.com>
+ <Reinhard.Pfau@gmx.de>
+
AUTOMAKE_OPTIONS = foreign
-SUBDIRS = asyncio glue_t2n unittest doc
+SUBDIRS = utils asyncio glue_t2n unittest doc
EXTRA_DIST+= LICENSE
+libasyncio
+===========
+
+a library providing an infrastructure for dealing with asnychronous
+io and support event driven programming.
+
+The basic idea for this lib is to provide classes which hide the details
+of polling/selecting for events on file descriptors and provide a more
+convenient interface which supports the idea of event driven programming.
+
+
+The library was originally developed by Intra2net as part of the
+Intranator connection daemon which is part of the Intranator (see http://www.intranator.com/).
+During development it was extracted as a separate module.
+And then we decide to publish it under The GNU Lesser Public License (LGPL).
+
+
+
+The libasyncio provides:
+
+- basic class for handling reading from and writing to fd's
+- filter plugin support for incoming/outgoing data.
+- timer events
+- deferred function calls; "frozen" function calls
+- start and handle subprocesses (connecting to their stdin/stdout/stderr)
+- unix domain socket handling
+- event signals (using boost-signal lib)
+- ... and some more stuff.
+
+
+It depend on the boost library (see http://www.boost.org/).
+
+
+Links:
+======
+
+the boost library: http://www.boost.org/
+Intra2net: http://www.intra2net.com/
+TODO list
+==========
+
+optimize, consolidate, beautify (a never ending task :-) )
+
+
-INCLUDES = @LIBI2NCOMMON_CFLAGS@ @BOOST_CPPFLAGS@
+INCLUDES = -I$(top_srcdir)/utils @BOOST_CPPFLAGS@ @LIBI2NCOMMON_CFLAGS@
METASOURCES = AUTO
lib_LTLIBRARIES = libasyncio.la
libasyncio_la_SOURCES = async_callout.cpp async_io.cpp async_pipe.cpp \
libasyncio_la_LDFLAGS = -version-info @LIBASYNCIO_LIB_VERSION@
-pkgconfigdir=$(libdir)/pkgconfig
+pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA= libasyncio.pc
+
+$(top_srcdir)/headerlist.asyncio: $(include_HEADERS)
+ list='$(include_HEADERS)'; \
+ ( for n in $$list; do echo $(includedir)/$$n ; done) > $@
+
+.PHONY: headerlist
+headerlist: $(top_srcdir)/headerlist.asyncio
#define ODOUT(msg) do {} while (0)
#endif
+
namespace
{
+using namespace AsyncIo::Utils;
/*
* configuration:
}; // eo struct PollDataCluster
-template<class T>
-class PtrList : public std::list<T*>
-{
- typedef std::list<T*> inherited;
- public:
- bool dirty;
-
- static int Instances;
-
- public:
-
- PtrList()
- : dirty(false)
- {
- ++Instances;
- } // eo PtrList
-
-
- ~PtrList()
- {
- ODOUT("");
- --Instances;
- }
-
-
- /**
- * add a new item pointer to the list.
- *
- * @param item item pointer which should be added
- */
- void add_item(T* item)
- {
- typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
- if (it != inherited::end())
- {
- // nothing to do since item is already in the list
- return;
- }
- push_back(item);
- } // eo add
-
-
- /**
- * remove an item pointer from the list by setting NULL at the current position of the item and mark
- * the list as dirty.
- *
- * @param item the io object which should be removed from the list.
- */
- void remove_item(T* item)
- {
- typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
- if (it == inherited::end())
- {
- // nothing to do:
- return;
- }
- *it = NULL; // forget the pointer
- dirty= true; // ..and mark the list as dirty (i.e. has NULL elements)
- } // eo remove
-
-
- /**
- * cleans the list of objects by removing the NULL elements (if any).
- *
- * @note this function should only be called when it is ensured that no other functions using iterators of this list.
- */
- void clean_list()
- {
- if (!dirty)
- {
- // nothing to do
- return;
- }
- // remove the NULL elements now:
- erase(
- std::remove( inherited::begin(), inherited::end(), (T*)NULL),
- inherited::end() );
- dirty= false;
- } // eo clean_list
-
-
-}; // eo class PtrList
-
-
-typedef PtrList<AsyncIo::IOImplementation> IOList;
-typedef PtrList<AsyncIo::TimerBase> TimerList;
+typedef PtrList< AsyncIo::IOImplementation, true > IOList;
+typedef PtrList< AsyncIo::TimerBase, true > TimerList;
-template<> int IOList::Instances= 0;
-template<> int TimerList::Instances= 0;
+template<> int IOList::GlobalCountType::InstanceCount= 0;
+template<> int TimerList::GlobalCountType::InstanceCount= 0;
/**
}; // eo struct FilterMatch
-void get_current_real_time(long& current_sec, long& current_msec)
-{
- struct timeval tv;
- gettimeofday(&tv,NULL);
- current_sec= tv.tv_sec;
- current_msec= (tv.tv_usec / 1000);
- if (current_msec >= 1000)
- {
- current_sec += (current_msec / 1000);
- current_msec%= 1000;
- }
-} // eo get_current_real_time
-
-
-void get_current_monotonic_time(long& current_sec, long& current_msec)
-{
- long nsec;
- if (monotonic_clock_gettime(current_sec,nsec))
- {
- current_msec= nsec / 1000000L;
- }
- else
- {
- //fallback...
- get_current_real_time(current_sec,current_msec);
- }
-} // eo get_current_monotonic_time
-
-
} // eo anonymous namespace
{
-/**
- * @brief gets the current time as MilliTime structure.
- * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
- */
-void get_current_real_time(MilliTime& mt)
-{
- long sec, msec;
- ::get_current_real_time(sec,msec);
- mt.set(sec,msec);
-} // eo get_current_real_time
-
-
-/**
- * @brief gets the current time as MilliTime structure.
- * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
- */
-void get_current_monotonic_time(MilliTime& mt)
-{
- long sec, msec;
- ::get_current_monotonic_time(sec,msec);
- mt.set(sec,msec);
-} // eo get_current_monotonic_time
-
-
-/*
- * implementation of MilliTime
- */
-
-MilliTime::MilliTime(long sec, long msec)
-: mt_sec(sec), mt_msec(msec)
-{
- normalize();
-} // eo MilliTime::MilliTime
-
-
-void MilliTime::set(long sec, long msec)
-{
- mt_sec= sec;
- mt_msec= msec;
- normalize();
-} // eo MilliTime::set
-
-
-/**
- * normalizes the values, so that mt_msec has a value between 0 and 999.
- */
-void MilliTime::normalize()
-{
- if (mt_msec < 0)
- {
- mt_sec += (mt_msec / 1000) - 1;
- mt_msec = (mt_msec % 1000) + 1000;
- }
- else if (mt_msec>=1000)
- {
- mt_sec+= (mt_msec / 1000);
- mt_msec %= 1000;
- }
-} // eo MilliTime::normalize
-
-
-/**
- * determine if the represented point in time is before another one.
- * @param other the other point in time.
- * @return true if the own point in time is before the other one.
- */
-bool MilliTime::operator < (MilliTime& other)
-{
- normalize();
- other.normalize();
- return
- (mt_sec < other.mt_sec)
- || (( mt_sec == other.mt_sec) && (mt_msec < other.mt_msec));
-} // eo MilliTime::operator <
-
-
-/**
- * determine if two point in times are equal.
- * @param other the point in time to compare with.
- * @return true if the represented times are equal.
- */
-bool MilliTime::operator == (MilliTime& other)
-{
- normalize();
- other.normalize();
- return (( mt_sec == other.mt_sec) && (mt_msec == other.mt_msec));
-} // eo MilliTime::operator <
-
-/**
- * @brief subtracts a time delta from the object.
- * @param lhs the time delta to subtract.
- * @return reference to the object itself.
- */
-MilliTime& MilliTime::operator -= (const MilliTime& lhs)
-{
- mt_sec -= lhs.mt_sec;
- mt_msec -= lhs.mt_msec;
-} // eo operator -=
-
-
-/**
- * @brief adds a time delta from the object.
- * @param lhs the time delta to add.
- * @return reference to the object itself.
- */
-MilliTime& MilliTime::operator += (const MilliTime& lhs)
-{
- mt_sec += lhs.mt_sec;
- mt_msec += lhs.mt_msec;
-} // eo operator +=
-
-
/*
* implementation of TimerBase
*/
TimerBase::~TimerBase()
{
ODOUT("enter");
- if (internal_io::TimerList::Instances)
+ if (internal_io::TimerList::Instances())
{
ODOUT("remove from list");
internal_io::g_timer_list().remove_item(this);
IOImplementation::~IOImplementation()
{
close();
- if (internal_io::IOList::Instances)
+ if (internal_io::IOList::Instances())
{
internal_io::g_io_list().remove_item(this);
}
#include <list>
#include <set>
+#include <asyncio_utils.hpp>
+
#include <pointer_func.hpp>
#include <boost/signal.hpp>
{
using namespace I2n;
-
+using Utils::MilliTime;
/*
* forward declarations
}; // eo struct IODirection;
-/**
- * structure for storing (a point in time as) seconds and milliseconds.
- */
-struct MilliTime
-{
- long mt_sec;
- long mt_msec;
-
- MilliTime(long sec=0, long msec=0);
-
- void set(long sec, long msec=0);
-
- inline long long get_milliseconds() const
- {
- return ((long long)mt_sec * 1000L + mt_msec);
- } // eo get_milliseconds
-
- void normalize();
-
- bool operator < (MilliTime& other);
- bool operator == (MilliTime& other);
-
- MilliTime& operator -= (const MilliTime& lhs);
- MilliTime& operator += (const MilliTime& lhs);
-
-}; // eo struct MilliTime
-
-
-inline MilliTime operator + (const MilliTime& rhs, const MilliTime& lhs)
-{
- MilliTime t(rhs);
- return t+= lhs;
-} // eo operator + (const MilliTime& rhs, const MilliTime lhs)
-
-inline MilliTime operator - (const MilliTime& rhs, const MilliTime& lhs)
-{
- MilliTime t(rhs);
- return t-= lhs;
-} // eo operator - (const MilliTime& rhs, const MilliTime lhs)
-
-
-inline bool operator <= (MilliTime& rhs, MilliTime& lhs)
-{
- return (rhs<lhs) || (rhs==lhs);
-} // eo operator <= (MilliTime& rhs, MilliTime& lhs)
-
-
/**
* base class for time based events (timer events).
-/*
-** tool functions:
-*/
-
-
-void get_current_real_time(MilliTime& mt);
-void get_current_monotonic_time(MilliTime& mt);
-
-
} // eo namespace AsyncIo
#endif
libdir=@libdir@
includedir=@includedir@
-Name: libsimpleio
+Name: libasyncio
Description: asynchrounous io lib
Version: @VERSION@
-Requires: libi2ncommon
-Libs: -L${libdir} -lsimpleio
+Requires: asyncio_utils libi2ncommon
+Libs: -L${libdir} -lasyncio
Cflags: -I${includedir}
dnl spit out the result files:
-AC_OUTPUT(Makefile doc/Makefile doc/Doxyfile glue_t2n/Makefile asyncio/Makefile \
- unittest/Makefile \
- asyncio/libasyncio.pc glue_t2n/libasyncio_t2n.pc
-)
+AC_OUTPUT(Makefile asyncio/Makefile asyncio/libasyncio.pc doc/Doxyfile \
+ utils/libasyncio_utils.pc \
+ doc/Makefile glue_t2n/Makefile glue_t2n/libasyncio_t2n.pc unittest/Makefile utils/Makefile)
all: $(MANUALS)
-html/index.html: $(top_srcdir)/asyncio/*.cpp $(top_srcdir)/asyncio/*.hpp $(top_srcdir)/glue_t2n/*.hpp $(top_srcdir)/glue_t2n/*.cpp $(srcdir)/index.doc Doxyfile
+html/index.html: $(top_srcdir)/asyncio/*.cpp $(top_srcdir)/asyncio/*.hpp $(top_srcdir)/glue_t2n/*.hpp $(top_srcdir)/glue_t2n/*.cpp $(srcdir)/index.doc $(top_srcdir)/utils/*.hpp $(top_srcdir)/utils/*.cpp Doxyfile
$(DOXYGEN)
EXTRA_DIST = index.doc Doxyfile.in
-INCLUDES = -I$(top_srcdir)/asyncio @LIBT2N_CFLAGS@ @BOOST_CPPFLAGS@ \
- @LIBI2NCOMMON_CFLAGS@
+INCLUDES = -I$(top_srcdir)/asyncio -I$(top_srcdir)/utils @BOOST_CPPFLAGS@ \
+ @LIBI2NCOMMON_CFLAGS@ @LIBT2N_CFLAGS@
METASOURCES = AUTO
lib_LTLIBRARIES = libasyncio_t2n.la
libasyncio_t2n_la_LIBADD = $(top_builddir)/asyncio/libasyncio.la \
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA= libasyncio_t2n.pc
-include_HEADERS = async_io_t2n.hpp
-libasyncio_t2n_la_SOURCES = async_io_t2n.cpp
+include_HEADERS = asyncio_t2n.hpp
+libasyncio_t2n_la_SOURCES = asyncio_t2n.cpp
* @contact info@intra2net.com
*/
-#include "async_io_t2n.hpp"
+#include "asyncio_t2n.hpp"
#include <iostream>
#include <boost/type_traits/is_base_of.hpp>
namespace AsyncIo
{
+using namespace Utils;
namespace
{
* @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
*
* @copyright © Copyright 2008 Intra2Net AG
- * @license commercial
+ * @license LGPL
* @contact info@intra2net.com
*
*/
* @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
*
* @copyright © Copyright 2008 Intra2Net AG
- * @license commercial
+ * @license LPGL
* @contact info@intra2net.com
*
*/
-INCLUDES = -I$(top_srcdir)/. -I$(top_srcdir)/common -I$(top_srcdir)/connd \
- -I$(top_srcdir)/simpleio @BOOST_CPPFLAGS@ @CPPUNIT_CFLAGS@ @LIBI2NCOMMON_CFLAGS@
+INCLUDES = -I$(top_srcdir)/. -I$(top_srcdir)/asyncio -I$(top_srcdir)/utils \
+ @BOOST_CPPFLAGS@ @CPPUNIT_CFLAGS@ @LIBI2NCOMMON_CFLAGS@
METASOURCES = AUTO
check_PROGRAMS = testsimpleio
testsimpleio_SOURCES = test.cpp test_simpleio_basics.cpp
-testsimpleio_LDADD = $(top_builddir)/simpleio/libsimpleio.la @BOOST_LDFLAGS@ \
- @BOOST_SIGNALS_LIB@ @CPPUNIT_LIBS@ @LIBI2NCOMMON_LIBS@
+testsimpleio_LDADD = $(top_builddir)/utils/libasyncio_utils.la \
+ $(top_builddir)/asyncio/libasyncio.la @BOOST_LDFLAGS@ @BOOST_SIGNALS_LIB@ @CPPUNIT_LIBS@ @LIBI2NCOMMON_LIBS@
TESTS = testsimpleio
using namespace I2n;
-using namespace I2n::AsyncIo;
+using namespace AsyncIo;
using namespace CppUnit;
--- /dev/null
+INCLUDES = @BOOST_CPPFLAGS@
+METASOURCES = AUTO
+lib_LTLIBRARIES = libasyncio_utils.la
+include_HEADERS = asyncio_ptr_list.hpp asyncio_utils.hpp asyncio_time_tools.hpp
+libasyncio_utils_la_SOURCES = asyncio_time_tools.cpp asyncio_utils.cpp
+
+libasyncio_utils_la_LDFLAGS = -version-info @LIBASYNCIO_LIB_VERSION@
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA= libasyncio_utils.pc
+
+
+$(top_srcdir)/headerlist.utils: $(include_HEADERS)
+ list='$(include_HEADERS)'; \
+ ( for n in $$list; do echo $(includedir)/$$n ; done) > $@
+
+.PHONY: headerlist
+headerlist: $(top_srcdir)/headerlist.utils
--- /dev/null
+/**
+ * @file
+ * @brief a pointer list
+ *
+ * provides a pointer list which is prepared for being used in nested
+ * iterator loops.
+ *
+ * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
+ *
+ * @copyright © Copyright 2008 Intra2Net AG
+ * @license LGPL
+ * @contact info@intra2net.com
+ *
+ */
+
+#ifndef __ASYNCIO__PTR_LIST_HPP__
+#define __ASYNCIO__PTR_LIST_HPP__
+
+#include <list>
+#include <algorithm>
+
+
+namespace AsyncIo
+{
+namespace Utils
+{
+
+
+/**
+ * @brief provides a global instance counter.
+ *
+ * The global instance counter must be initialized by the module which uses it.
+ * The main purpose for this is to keep track of the instances when PtrList's are
+ * used as global objects.
+ */
+template< class T, bool globalcounted >
+class GlobalCounted
+{
+ static int InstanceCount;
+
+ public:
+
+ GlobalCounted()
+ {
+ ++InstanceCount;
+ } // eo GlobalCounted
+
+
+ virtual ~GlobalCounted()
+ {
+ --InstanceCount;
+ } // eo ~GlobalCounted
+
+ static int Instances()
+ {
+ return InstanceCount;
+ }
+}; // eo GlobalCounted
+
+
+template<>
+class GlobalCounted< class T, false >
+{
+ public:
+ GlobalCounted()
+ {
+ } // eo GlobalCounted
+
+
+ virtual ~GlobalCounted()
+ {
+ } // eo ~GlobalCounted
+
+}; // eo GlobalCounted
+
+
+
+/**
+ * @brief pointer list which supports deletion by set to NULL.
+ *
+ * This list can be used in nested iterator loops as long as some conditions
+ * are fulfilled:
+ * - inside the loops each iterator value is tested for not get NULL.
+ * - cleaning the list is only allowed when the outmost loop exits.
+ * .
+ *
+ *
+ * @tparam T type of the pointers.
+ * @tparam globalcounted determine if a global instance counter should be included.
+ */
+template<class T, bool globalcounted= false>
+class PtrList
+: public GlobalCounted< PtrList< T, globalcounted >, globalcounted >
+, protected std::list<T*>
+{
+ typedef std::list<T*> inherited;
+
+ public:
+ typedef GlobalCounted< PtrList< T, globalcounted >, globalcounted > GlobalCountType;
+
+ typedef typename inherited::iterator iterator;
+ typedef typename inherited::const_iterator const_iterator;
+
+ public:
+
+ PtrList()
+ : Dirty(false)
+ {
+ } // eo PtrList
+
+
+ ~PtrList()
+ {
+ } // eo ~PtrList
+
+
+ /**
+ * @brief add a new item pointer to the list.
+ *
+ * @param item item pointer which should be added
+ */
+ void add_item(T* item)
+ {
+ typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
+ if (it != inherited::end())
+ {
+ // nothing to do since item is already in the list
+ return;
+ }
+ push_back(item);
+ } // eo add
+
+
+ /**
+ * @brief remove an item pointer from the list by setting to NULL.
+ *
+ * This sets the pointer in the list to NULL and marks the list as dirty.
+ *
+ * @param item the io object which should be removed from the list.
+ */
+ void remove_item(T* item)
+ {
+ typename inherited::iterator it= std::find(inherited::begin(), inherited::end(), item);
+ if (it == inherited::end())
+ {
+ // nothing to do:
+ return;
+ }
+ *it = NULL; // forget the pointer
+ Dirty= true; // ..and mark the list as dirty (i.e. has NULL elements)
+ } // eo remove
+
+
+ /**
+ * @brief cleans the list of objects by removing the NULL elements (if any).
+ *
+ * @note this function should only be called when it is ensured that no
+ * other functions using iterators of this list.
+ */
+ void clean_list()
+ {
+ if (!Dirty)
+ {
+ // nothing to do
+ return;
+ }
+ // remove the NULL elements now:
+ erase(
+ std::remove( inherited::begin(), inherited::end(), (T*)NULL),
+ inherited::end() );
+ Dirty= false;
+ } // eo clean_list
+
+
+ /**
+ * @brief explicit set the list dirty.
+ *
+ * use this to mark the list as dirty, when an item is set to NULL via
+ * a non const iterator.
+ *
+ * @note This is really dirty; better use remove_item(T*) in that cases!
+ */
+ void set_dirty()
+ {
+ Dirty= true;
+ } // eo set_dirty
+
+
+ iterator begin()
+ {
+ return inherited::begin();
+ }
+
+
+ iterator end()
+ {
+ return inherited::end();
+ }
+
+
+ const_iterator begin() const
+ {
+ return inherited::begin();
+ }
+
+
+ const_iterator end() const
+ {
+ return inherited::end();
+ }
+
+ protected:
+ bool Dirty;
+
+}; // eo class PtrList
+
+
+} // eo namespace Utils
+} // eo namespace AsyncIo
+
+#endif
--- /dev/null
+/**
+ * @file
+ * @brief
+ *
+ * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
+ *
+ * @copyright © Copyright 2008 Intra2Net AG
+ * @license LGPL
+ * @contact info@intra2net.com
+ *
+ */
+
+#include "asyncio_time_tools.hpp"
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/timeb.h>
+#include <sys/syscall.h>
+
+
+// define missing POSIX.1b constants...
+
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+#endif
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC 1
+#endif
+
+namespace AsyncIo
+{
+namespace Utils
+{
+
+
+namespace
+{
+
+
+/**
+ * @brief fetches the value from the monotonic clock source.
+ * @param[out] seconds the seconds.
+ * @param[out] nano_seconds the nano seconds.
+ * @return @a true if the clock was successfully read.
+ */
+bool monotonic_clock_gettime(long int& seconds, long int& nano_seconds)
+{
+ struct timespec tp[1];
+ int res= ::syscall(__NR_clock_gettime, CLOCK_MONOTONIC, tp);
+ if (0 == res)
+ {
+ seconds= tp->tv_sec;
+ nano_seconds= tp->tv_nsec;
+ }
+ return (res==0);
+} // eo monotonic_clock_gettime(long int&,long int&)
+
+
+
+
+void get_current_real_time(long& current_sec, long& current_msec)
+{
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ current_sec= tv.tv_sec;
+ current_msec= (tv.tv_usec / 1000);
+ if (current_msec >= 1000)
+ {
+ current_sec += (current_msec / 1000);
+ current_msec%= 1000;
+ }
+} // eo get_current_real_time
+
+
+void get_current_monotonic_time(long& current_sec, long& current_msec)
+{
+ long nsec;
+ if (monotonic_clock_gettime(current_sec,nsec))
+ {
+ current_msec= nsec / 1000000L;
+ }
+ else
+ {
+ //fallback...
+ get_current_real_time(current_sec,current_msec);
+ }
+} // eo get_current_monotonic_time
+
+
+
+} // eo anonymous namespace
+
+/**************************************************************************\
+\**************************************************************************/
+
+
+/*
+ * implementation of MilliTime
+ */
+
+MilliTime::MilliTime(long sec, long msec)
+: mt_sec(sec), mt_msec(msec)
+{
+ normalize();
+} // eo MilliTime::MilliTime
+
+
+void MilliTime::set(long sec, long msec)
+{
+ mt_sec= sec;
+ mt_msec= msec;
+ normalize();
+} // eo MilliTime::set
+
+
+/**
+ * normalizes the values, so that mt_msec has a value between 0 and 999.
+ */
+void MilliTime::normalize()
+{
+ if (mt_msec < 0)
+ {
+ mt_sec += (mt_msec / 1000) - 1;
+ mt_msec = (mt_msec % 1000) + 1000;
+ }
+ else if (mt_msec>=1000)
+ {
+ mt_sec+= (mt_msec / 1000);
+ mt_msec %= 1000;
+ }
+} // eo MilliTime::normalize
+
+
+/**
+ * determine if the represented point in time is before another one.
+ * @param other the other point in time.
+ * @return true if the own point in time is before the other one.
+ */
+bool MilliTime::operator < (MilliTime& other)
+{
+ normalize();
+ other.normalize();
+ return
+ (mt_sec < other.mt_sec)
+ || (( mt_sec == other.mt_sec) && (mt_msec < other.mt_msec));
+} // eo MilliTime::operator <
+
+
+/**
+ * determine if two point in times are equal.
+ * @param other the point in time to compare with.
+ * @return true if the represented times are equal.
+ */
+bool MilliTime::operator == (MilliTime& other)
+{
+ normalize();
+ other.normalize();
+ return (( mt_sec == other.mt_sec) && (mt_msec == other.mt_msec));
+} // eo MilliTime::operator <
+
+/**
+ * @brief subtracts a time delta from the object.
+ * @param lhs the time delta to subtract.
+ * @return reference to the object itself.
+ */
+MilliTime& MilliTime::operator -= (const MilliTime& lhs)
+{
+ mt_sec -= lhs.mt_sec;
+ mt_msec -= lhs.mt_msec;
+} // eo operator -=
+
+
+/**
+ * @brief adds a time delta from the object.
+ * @param lhs the time delta to add.
+ * @return reference to the object itself.
+ */
+MilliTime& MilliTime::operator += (const MilliTime& lhs)
+{
+ mt_sec += lhs.mt_sec;
+ mt_msec += lhs.mt_msec;
+} // eo operator +=
+
+
+
+/**
+ * @brief gets the current time as MilliTime structure.
+ * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
+ */
+void get_current_real_time(MilliTime& mt)
+{
+ long sec, msec;
+ get_current_real_time(sec,msec);
+ mt.set(sec,msec);
+} // eo get_current_real_time
+
+
+/**
+ * @brief gets the current time as MilliTime structure.
+ * @param[out] mt reference to the MilliTime strcucture which is filled with the result.
+ */
+void get_current_monotonic_time(MilliTime& mt)
+{
+ long sec, msec;
+ get_current_monotonic_time(sec,msec);
+ mt.set(sec,msec);
+} // eo get_current_monotonic_time
+
+
+
+
+
+} // eo namespace Utils
+} // eo namespace AsyncIo
--- /dev/null
+/**
+ * @file
+ * @brief
+ *
+ * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
+ *
+ * @copyright © Copyright 2008 Intra2Net AG
+ * @license LPGL
+ * @contact info@intra2net.com
+ *
+ */
+
+#ifndef __ASYNCIO__TIME_TOOLS_HPP__
+#define __ASYNCIO__TIME_TOOLS_HPP__
+
+namespace AsyncIo
+{
+namespace Utils
+{
+
+/**
+ * @brief structure for storing (a point in time as) seconds and milliseconds.
+ */
+struct MilliTime
+{
+ long mt_sec;
+ long mt_msec;
+
+ MilliTime(long sec=0, long msec=0);
+
+ void set(long sec, long msec=0);
+
+ inline long long get_milliseconds() const
+ {
+ return ((long long)mt_sec * 1000L + mt_msec);
+ } // eo get_milliseconds
+
+ void normalize();
+
+ bool operator < (MilliTime& other);
+ bool operator == (MilliTime& other);
+
+ MilliTime& operator -= (const MilliTime& lhs);
+ MilliTime& operator += (const MilliTime& lhs);
+
+}; // eo struct MilliTime
+
+
+inline MilliTime operator + (const MilliTime& rhs, const MilliTime& lhs)
+{
+ MilliTime t(rhs);
+ return t+= lhs;
+} // eo operator + (const MilliTime& rhs, const MilliTime lhs)
+
+inline MilliTime operator - (const MilliTime& rhs, const MilliTime& lhs)
+{
+ MilliTime t(rhs);
+ return t-= lhs;
+} // eo operator - (const MilliTime& rhs, const MilliTime lhs)
+
+
+inline bool operator <= (MilliTime& rhs, MilliTime& lhs)
+{
+ return (rhs<lhs) || (rhs==lhs);
+} // eo operator <= (MilliTime& rhs, MilliTime& lhs)
+
+
+
+/*
+** tool functions:
+*/
+
+
+void get_current_real_time(MilliTime& mt);
+void get_current_monotonic_time(MilliTime& mt);
+
+
+} // eo namespace Utils
+} // eo namespace AsyncIo
+
+
+
+#endif
\ No newline at end of file
--- /dev/null
+/**
+ * @file
+ * @brief
+ *
+ * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
+ *
+ * @copyright © Copyright 2008 Intra2Net AG
+ * @license LGPL
+ * @contact info@intra2net.com
+ *
+ */
+
+namespace AsyncIo
+{
+namespace Utils
+{
+
+
+
+} // eo namespace Utils
+} // eo namespace AsyncIo
--- /dev/null
+/**
+ * @file
+ * @brief convenience file for including all util header at once.
+ *
+ * @author Reinhard Pfau \<reinhard.pfau@intra2net.com\>
+ *
+ * @copyright © Copyright 2008 Intra2Net AG
+ * @license LPGL
+ * @contact info@intra2net.com
+ *
+ */
+
+
+#include "asyncio_ptr_list.hpp"
+#include "asyncio_time_tools.hpp"
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libasyncio_utils
+Description: utils for the asynchrounous io lib
+Version: @VERSION@
+Libs: -L${libdir} -lasyncio_utils
+Cflags: -I${includedir}