-## $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
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..
check_PROGRAMS = \
test_package1 \
+ test_pipe \
test_filter1 test_filter2 \
test_session1 test_session2 \
test_thread_pool_observer \
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
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)
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)
--- /dev/null
+
+/* $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 <unistd.h>
+#endif
+
+#ifdef WIN32
+#include <winsock.h>
+#else
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#endif
+
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+#include <stdio.h>
+
+#include <deque>
+
+#include <yaz++/socket-observer.h>
+#include <yaz/log.h>
+
+#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
+ */
+
--- /dev/null
+/* $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 <boost/scoped_ptr.hpp>
+
+#include <yaz/yconfig.h>
+
+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<Rep> m_p;
+ };
+}
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * c-file-style: "stroustrup"
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
--- /dev/null
+/* $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 <yaz++/socket-manager.h>
+
+#include <iostream>
+#include <stdexcept>
+
+#include "util.hpp"
+#include "pipe.hpp"
+
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+
+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
+ */