+
// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
#include "Scheduler.hh"
-#include <boost/test/auto_unit_test.hpp>
+#include "../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-using namespace satcom::lib;
+using namespace senf;
namespace {
-
+
char const * SOCK_PATH = "/tmp/sched_test.sock";
-
+
void error(char const * fn, char const * proc="")
{
std::cerr << "\n" << proc << fn << ": " << strerror(errno) << std::endl;
error("fork");
return 0;
}
-
+
sleep(1); // Wait for the server socket to be opened
return pid;
}
void callback(int fd, Scheduler::EventId ev)
{
event = ev;
- switch (event) {
+ switch (event & Scheduler::EV_ALL) {
case Scheduler::EV_READ:
size = recv(fd,buffer,1024,0);
break;
size = write(fd,buffer,size);
Scheduler::instance().terminate();
break;
- case Scheduler::EV_HUP:
- case Scheduler::EV_ERR:
- case Scheduler::EV_NONE:
- case Scheduler::EV_ALL:
- ;
}
Scheduler::instance().terminate();
}
- void timeout()
+ void timeout()
{
- Scheduler::instance().terminate();
+ Scheduler::instance().terminate();
}
-
+
struct HandleWrapper
{
HandleWrapper(int fd,std::string const & tag) : fd_(fd), tag_(tag) {}
callback(handle.fd_,event);
}
- bool is_close(MicroTime a, MicroTime b)
+ bool is_close(ClockService::clock_type a, ClockService::clock_type b)
+ {
+ return (a<b ? b-a : a-b) < ClockService::milliseconds(100);
+ }
+
+ ClockService::clock_type sigtime (0);
+
+ void sigusr()
+ {
+ sigtime = ClockService::now();
+ Scheduler::instance().terminate();
+ }
+
+ void delay(unsigned long milliseconds)
{
- return (a<b ? b-a : a-b) < 10100; // a little bit over 10ms
+ struct timespec ts;
+ ts.tv_sec = milliseconds / 1000;
+ ts.tv_nsec = (milliseconds % 1000) * 1000000;
+ while (nanosleep(&ts,&ts) < 0 && errno == EINTR) ;
}
-
}
BOOST_AUTO_UNIT_TEST(scheduler)
memset(&sun,0,sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,SOCK_PATH);
-
+
if (connect(sock,(struct sockaddr*)&sun,sizeof(sun))<0) {
error("connect");
BOOST_FAIL("connect");
BOOST_CHECK_NO_THROW( Scheduler::instance() );
- BOOST_CHECK_NO_THROW( Scheduler::instance().add(sock,&callback,Scheduler::EV_READ) );
+ BOOST_CHECK_NO_THROW( Scheduler::instance().add(sock,boost::bind(&callback, sock, _1),
+ Scheduler::EV_READ) );
event = Scheduler::EV_NONE;
BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
BOOST_CHECK_EQUAL( event, Scheduler::EV_READ );
buffer[size]=0;
BOOST_CHECK_EQUAL( buffer, "READ" );
- BOOST_CHECK_NO_THROW( Scheduler::instance().timeout(100,&timeout) );
- BOOST_CHECK_NO_THROW( Scheduler::instance().timeout(200,&timeout) );
- MicroTime t (now());
+ BOOST_CHECK_NO_THROW( Scheduler::instance().timeout(
+ ClockService::now()+ClockService::milliseconds(200),&timeout) );
+ BOOST_CHECK_NO_THROW( Scheduler::instance().timeout(
+ ClockService::now()+ClockService::milliseconds(400),&timeout) );
+ ClockService::clock_type t (ClockService::now());
BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
- BOOST_CHECK_PREDICATE( is_close, (now()) (t+100*1000) );
+ BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (t+ClockService::milliseconds(200)) );
BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
- BOOST_CHECK_PREDICATE( is_close, (now()) (t+200*1000) );
-
+ BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (t+ClockService::milliseconds(400)) );
+
HandleWrapper handle(sock,"TheTag");
- BOOST_CHECK_NO_THROW( Scheduler::instance().add(handle,&handleCallback,Scheduler::EV_WRITE) );
+ BOOST_CHECK_NO_THROW( Scheduler::instance().add(handle,
+ boost::bind(&handleCallback,handle,_1),
+ Scheduler::EV_WRITE) );
strcpy(buffer,"WRITE");
size=5;
event = Scheduler::EV_NONE;
BOOST_CHECK_NO_THROW( Scheduler::instance().remove(handle,Scheduler::EV_WRITE) );
event = Scheduler::EV_NONE;
+ sleep(1);
BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
- BOOST_CHECK_EQUAL( event, Scheduler::EV_READ );
+ BOOST_CHECK_EQUAL( event, Scheduler::EventId(Scheduler::EV_READ|Scheduler::EV_HUP) );
BOOST_REQUIRE_EQUAL( size, 2 );
buffer[size]=0;
BOOST_CHECK_EQUAL( buffer, "OK" );
+ BOOST_CHECK_NO_THROW( Scheduler::instance().remove(handle) );
+
+ unsigned tid (Scheduler::instance().timeout(
+ ClockService::now()+ClockService::milliseconds(400),&timeout));
+ BOOST_CHECK_NO_THROW( Scheduler::instance().registerSignal(SIGUSR1, &sigusr) );
+ t = ClockService::now();
+ ::kill(::getpid(), SIGUSR1);
+ delay(100);
+ BOOST_CHECK_NO_THROW( Scheduler::instance().process() );
+ BOOST_CHECK_PREDICATE( is_close, (ClockService::now()) (t+ClockService::milliseconds(200)) );
+ BOOST_CHECK_PREDICATE( is_close, (sigtime) (t+ClockService::milliseconds(200)) );
+ Scheduler::instance().cancelTimeout(tid);
+ BOOST_CHECK_NO_THROW( Scheduler::instance().unregisterSignal(SIGUSR1) );
///////////////////////////////////////////////////////////////////////////
\f
// Local Variables:
// mode: c++
-// c-file-style: "satcom"
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
// End: