From 7ccf90cb13451e3d024eff6239815f92aff6e51b Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 7 Nov 2005 12:32:01 +0000 Subject: [PATCH] First work on Pipe class --- src/Makefile.am | 8 +++- src/pipe.cpp | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pipe.hpp | 40 +++++++++++++++++ src/test_pipe.cpp | 70 +++++++++++++++++++++++++++++ 4 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 src/pipe.cpp create mode 100644 src/pipe.hpp create mode 100644 src/test_pipe.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 637659d..65192b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -## $Id: Makefile.am,v 1.32 2005-10-31 22:44:55 adam Exp $ +## $Id: Makefile.am,v 1.33 2005-11-07 12:32:01 adam Exp $ MAINTAINERCLEANFILES = Makefile.in config.in config.hpp @@ -22,6 +22,7 @@ libyp2_la_SOURCES = \ filter_virt_db.cpp filter_virt_db.hpp \ filter_z3950_client.cpp filter_z3950_client.hpp \ filter_backend_test.cpp filter_backend_test.hpp \ + pipe.cpp pipe.hpp \ util.cpp util.hpp # Rules for programs.. @@ -38,6 +39,7 @@ ex_router_flexml_SOURCES = ex_router_flexml.cpp check_PROGRAMS = \ test_package1 \ + test_pipe \ test_filter1 test_filter2 \ test_session1 test_session2 \ test_thread_pool_observer \ @@ -54,6 +56,7 @@ check_PROGRAMS = \ TESTS=$(check_PROGRAMS) test_package1_SOURCES=test_package1.cpp +test_pipe_SOURCES=test_pipe.cpp test_filter1_SOURCES=test_filter1.cpp test_filter2_SOURCES=test_filter2.cpp test_session1_SOURCES=test_session1.cpp @@ -72,6 +75,8 @@ test_router_flexml_SOURCES = test_router_flexml.cpp TESTLDADD = $(LDADD) -lboost_unit_test_framework +test_package1_LDADD = $(TESTLDADD) +test_pipe_LDADD = $(TESTLDADD) test_filter1_LDADD = $(TESTLDADD) test_filter2_LDADD = $(TESTLDADD) test_session1_LDADD = $(TESTLDADD) @@ -79,7 +84,6 @@ test_session2_LDADD = $(TESTLDADD) test_boost_threads_LDADD = $(TESTLDADD) test_boost_time_LDADD = $(TESTLDADD) test_thread_pool_observer_LDADD = $(TESTLDADD) -test_package1_LDADD = $(TESTLDADD) test_filter_factory_LDADD = $(TESTLDADD) test_filter_frontend_net_LDADD = $(TESTLDADD) test_filter_log_LDADD = $(TESTLDADD) diff --git a/src/pipe.cpp b/src/pipe.cpp new file mode 100644 index 0000000..f0306f4 --- /dev/null +++ b/src/pipe.cpp @@ -0,0 +1,127 @@ + +/* $Id: pipe.cpp,v 1.1 2005-11-07 12:32:01 adam Exp $ + Copyright (c) 2005, Index Data. + +%LICENSE% + */ +#include "config.hpp" + +#if HAVE_UNISTD_H +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#endif + +#if HAVE_SYS_SOCKET_H +#include +#endif +#if HAVE_SYS_SELECT_H +#include +#endif + +#include +#include +#include + +#include + +#include + +#include +#include + +#include "pipe.hpp" + +namespace yp2 { + class Pipe::Rep : public boost::noncopyable { + friend class Pipe; + Rep(); + int m_fd[2]; + int m_socket; + }; +} + +using namespace yp2; + +Pipe::Rep::Rep() +{ + m_fd[0] = m_fd[1] = -1; + m_socket = -1; +} + +Pipe::Pipe(int port_to_use) : m_p(new Rep) +{ + if (port_to_use) + { + m_p->m_socket = socket(AF_INET, SOCK_STREAM, 0); + if (m_p->m_socket < 0) + throw Pipe::Error("could not create socket"); + + m_p->m_fd[1] = socket(AF_INET, SOCK_STREAM, 0); + if (m_p->m_fd[1] < 0) + throw Pipe::Error("could not create socket"); + + struct sockaddr_in add; + add.sin_family = AF_INET; + add.sin_port = htons(port_to_use); + add.sin_addr.s_addr = INADDR_ANY; + struct sockaddr *addr = ( struct sockaddr *) &add; + + if (bind(m_p->m_socket, addr, sizeof(struct sockaddr_in))) + throw Pipe::Error("could not bind on socket"); + + if (listen(m_p->m_socket, 3) < 0) + throw Pipe::Error("could not listen on socket"); + + struct sockaddr caddr; + socklen_t caddr_len = sizeof(caddr); + m_p->m_fd[0] = accept(m_p->m_socket, &caddr, &caddr_len); + if (m_p->m_fd[0] < 0) + throw Pipe::Error("could not accept on socket"); + + if (connect(m_p->m_fd[1], addr, sizeof(addr)) < 0) + throw Pipe::Error("could not connect to socket"); + } + else + { + m_p->m_socket = 0; + pipe(m_p->m_fd); + } +} + +Pipe::~Pipe() +{ + if (m_p->m_fd[0] != -1) + close(m_p->m_fd[0]); + if (m_p->m_fd[1] != -1) + close(m_p->m_fd[1]); + if (m_p->m_socket != -1) + close(m_p->m_socket); +} + +int &Pipe::read_fd() const +{ + return m_p->m_fd[0]; +} + +int &Pipe::write_fd() const +{ + return m_p->m_fd[1]; +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * c-file-style: "stroustrup" + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/pipe.hpp b/src/pipe.hpp new file mode 100644 index 0000000..f5b2378 --- /dev/null +++ b/src/pipe.hpp @@ -0,0 +1,40 @@ +/* $Id: pipe.hpp,v 1.1 2005-11-07 12:32:01 adam Exp $ + Copyright (c) 2005, Index Data. + +%LICENSE% + */ + +#ifndef YP2_PIPE_HPP +#define YP2_PIPE_HPP + +#include + +#include + +namespace yp2 { + class Pipe { + class Error : public std::runtime_error { + public: + Error(const std::string msg) + : std::runtime_error("Pipe error: " + msg) {}; + }; + class Rep; + public: + Pipe(int port_to_use); + ~Pipe(); + int &read_fd() const; + int &write_fd() const; + private: + boost::scoped_ptr m_p; + }; +} +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * c-file-style: "stroustrup" + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/test_pipe.cpp b/src/test_pipe.cpp new file mode 100644 index 0000000..e4f09c8 --- /dev/null +++ b/src/test_pipe.cpp @@ -0,0 +1,70 @@ +/* $Id: test_pipe.cpp,v 1.1 2005-11-07 12:32:01 adam Exp $ + Copyright (c) 2005, Index Data. + +%LICENSE% + */ + +#include "config.hpp" + +#include + +#include +#include + +#include "util.hpp" +#include "pipe.hpp" + +#define BOOST_AUTO_TEST_MAIN +#include + +using namespace boost::unit_test; + +class My_Timer_Thread : public yazpp_1::ISocketObserver { +private: + yazpp_1::ISocketObservable *m_obs; + yp2::Pipe m_pipe; + bool m_timeout; +public: + My_Timer_Thread(yazpp_1::ISocketObservable *obs, int duration); + void socketNotify(int event); + bool timeout() { return m_timeout; }; +}; + + +My_Timer_Thread::My_Timer_Thread(yazpp_1::ISocketObservable *obs, + int duration) : + m_obs(obs), m_pipe(0), m_timeout(false) +{ + obs->addObserver(m_pipe.read_fd(), this); + obs->maskObserver(this, yazpp_1::SOCKET_OBSERVE_READ); + obs->timeoutObserver(this, duration); +} + +void My_Timer_Thread::socketNotify(int event) +{ + m_timeout = true; + m_obs->deleteObserver(this); +} + +BOOST_AUTO_TEST_CASE( test_pipe_1 ) +{ + yazpp_1::SocketManager mySocketManager; + + yp2::Pipe pipe(0); + + My_Timer_Thread t(&mySocketManager, 0); + + while (mySocketManager.processEvent() > 0) + if (t.timeout()) + break; + BOOST_CHECK (t.timeout()); +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * c-file-style: "stroustrup" + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ -- 1.7.10.4