Implemented FilterFrontendNet which is a network server based on
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 13 Oct 2005 20:06:45 +0000 (20:06 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 13 Oct 2005 20:06:45 +0000 (20:06 +0000)
YAZ/YAZ++.

13 files changed:
src/.cvsignore
src/Makefile.am
src/filter_frontend_net.cpp [new file with mode: 0644]
src/filter_frontend_net.hpp [new file with mode: 0644]
src/p2_frontend.h
src/package.hpp
src/session.cpp [new file with mode: 0644]
src/session.hpp
src/test_filter_frontend_net.cpp [new file with mode: 0644]
src/test_thread_pool_observer.cpp
src/thread_pool_observer.cpp
src/thread_pool_observer.h [deleted file]
src/thread_pool_observer.hpp [new file with mode: 0644]

index 658a82a..6b3317f 100644 (file)
@@ -4,15 +4,17 @@
 *.la
 stamp-h*
 config.hpp
+socket
 Makefile
 Makefile.in
 config.hpp.in
+test_boost_threads
+test_boost_time
 test_filter1
 test_filter2
+test_filter_frontend_net
+test_package1
+test_thread_pool_observer
 test_session1
 test_session2
-test_boost_threads
-test_boost_time
-design
 p2
-test_thread_pool_observer
index 229a720..1587d49 100644 (file)
@@ -1,51 +1,64 @@
-## $Id: Makefile.am,v 1.16 2005-10-13 12:28:55 adam Exp $
+## $Id: Makefile.am,v 1.17 2005-10-13 20:06:45 adam Exp $
 
 MAINTAINERCLEANFILES = Makefile.in config.in config.hpp
 
 AM_CXXFLAGS = $(YAZPPINC) $(XSLT_CFLAGS)
 
-YP2_INCHPP = session.hpp package.hpp filter.hpp router.hpp
+# Rules for the library..
+
+lib_LTLIBRARIES = libyp2.la
+libyp2_la_LDFLAGS = -version-info 0:0:0
+
+libyp2_la_SOURCES = filter_frontend_net.cpp filter_frontend_net.hpp \
+       session.cpp session.hpp package.hpp filter.hpp router.hpp \
+       thread_pool_observer.cpp thread_pool_observer.hpp
+
+# Rules for programs..
+
+LDADD= libyp2.la $(YAZPPLALIB) $(XSLT_LIBS)
 
 bin_PROGRAMS =
+noinst_PROGRAMS = p2 
+
+p2_SOURCES=p2_frontend.cpp p2_msg.cpp p2.cpp p2_frontend.h \
+ p2_config.cpp p2_config.h \
+ p2_backend.h p2_backend_dummy.cpp \
+ p2_modules.cpp p2_modules.h \
+ p2_xmlerror.cpp p2_xmlerror.h
+
+# Rules for test programs..
+
 check_PROGRAMS = \
        test_package1 \
        test_filter1 test_filter2 \
        test_session1 test_session2 \
        test_thread_pool_observer \
-       test_boost_threads test_boost_time
-noinst_PROGRAMS =  p2 
+       test_boost_threads test_boost_time \
+       test_filter_frontend_net
 
 TESTS=$(check_PROGRAMS)
 
-test_package1_SOURCES=test_package1.cpp $(YP2_INCHPP)
-test_filter1_SOURCES=test_filter1.cpp $(YP2_INCHPP)
-test_filter2_SOURCES=test_filter2.cpp $(YP2_INCHPP)
-test_session1_SOURCES=test_session1.cpp $(YP2_INCHPP)
-test_session2_SOURCES=test_session2.cpp $(YP2_INCHPP)
+test_package1_SOURCES=test_package1.cpp
+test_filter1_SOURCES=test_filter1.cpp
+test_filter2_SOURCES=test_filter2.cpp
+test_session1_SOURCES=test_session1.cpp
+test_session2_SOURCES=test_session2.cpp
 test_boost_threads_SOURCES=test_boost_threads.cpp
 test_boost_time_SOURCES=test_boost_time.cpp
-test_thread_pool_observer_SOURCES = test_thread_pool_observer.cpp \
-          thread_pool_observer.cpp thread_pool_observer.h
-
-p2_SOURCES=p2_frontend.cpp p2_msg.cpp p2.cpp p2_frontend.h \
- p2_config.cpp p2_config.h \
- p2_backend.h p2_backend_dummy.cpp \
- p2_modules.cpp p2_modules.h \
- p2_xmlerror.cpp p2_xmlerror.h \
- thread_pool_observer.cpp thread_pool_observer.h
-
+test_thread_pool_observer_SOURCES = test_thread_pool_observer.cpp
+test_filter_frontend_net_SOURCES = test_filter_frontend_net.cpp
 
-LDADD= $(YAZPPLALIB) $(XSLT_LIBS)
-TLDADD = $(LDADD) -lboost_unit_test_framework
+TESTLDADD = $(LDADD) -lboost_unit_test_framework
 
-test_filter1_LDADD = $(TLDADD)
-test_filter2_LDADD = $(TLDADD)
-test_session1_LDADD = $(TLDADD)
-test_session2_LDADD = $(TLDADD)
-test_boost_threads_LDADD = $(TLDADD)
-test_boost_time_LDADD = $(TLDADD)
-test_thread_pool_observer_LDADD = $(TLDADD)
-test_package1_LDADD = $(TLDADD)
+test_filter1_LDADD = $(TESTLDADD)
+test_filter2_LDADD = $(TESTLDADD)
+test_session1_LDADD = $(TESTLDADD)
+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_frontend_net_LDADD = $(TESTLDADD)
 
 # doxygen target
 dox:
diff --git a/src/filter_frontend_net.cpp b/src/filter_frontend_net.cpp
new file mode 100644 (file)
index 0000000..ed9a475
--- /dev/null
@@ -0,0 +1,270 @@
+
+
+#include "config.hpp"
+
+#include "filter.hpp"
+#include "router.hpp"
+#include "package.hpp"
+#include "thread_pool_observer.hpp"
+#include "filter_frontend_net.hpp"
+#include <yaz++/z-assoc.h>
+#include <yaz++/pdu-assoc.h>
+#include <yaz++/socket-manager.h>
+#include <yaz/log.h>
+
+#include <iostream>
+
+using namespace yp2;
+
+class P2_Session : public yazpp_1::Z_Assoc {
+public:
+    ~P2_Session();
+    P2_Session(yazpp_1::IPDU_Observable *the_PDU_Observable,
+              ThreadPoolSocketObserver *m_my_thread,
+              const Package *package);
+    int m_no_requests;
+private:
+    yazpp_1::IPDU_Observer* sessionNotify(
+        yazpp_1::IPDU_Observable *the_PDU_Observable,
+        int fd);
+    void recv_GDU(Z_GDU *apdu, int len);
+    
+    void failNotify();
+    void timeoutNotify();
+    void connectNotify();
+private:
+    ThreadPoolSocketObserver *m_my_thread;
+    Session m_session;
+    Origin m_origin;
+    bool m_delete_flag;
+    const Package *m_package;
+};
+
+
+class ThreadPoolPackage : public IThreadPoolMsg {
+public:
+    ThreadPoolPackage(Package *package, P2_Session *ses) :
+       m_session(ses), m_package(package) { };
+    ~ThreadPoolPackage();
+    IThreadPoolMsg *handle();
+    void result();
+    
+private:
+    P2_Session *m_session;
+    Package *m_package;
+    
+};
+
+ThreadPoolPackage::~ThreadPoolPackage()
+{
+    delete m_package;
+}
+
+void ThreadPoolPackage::result()
+{
+    m_session->m_no_requests--;
+
+    yazpp_1::GDU *gdu = &m_package->response();
+    if (gdu->get())
+    {
+       int len;
+       m_session->send_GDU(gdu->get(), &len);
+    }
+}
+
+IThreadPoolMsg *ThreadPoolPackage::handle() 
+{
+    m_package->move();
+    return this;
+}
+
+
+P2_Session::P2_Session(yazpp_1::IPDU_Observable *the_PDU_Observable,
+                      ThreadPoolSocketObserver *my_thread_pool,
+                      const Package *package)
+    :  Z_Assoc(the_PDU_Observable)
+{
+    m_my_thread = my_thread_pool;
+    m_no_requests = 0;
+    m_delete_flag = false;
+    m_package = package;
+}
+
+
+yazpp_1::IPDU_Observer *P2_Session::sessionNotify(yazpp_1::IPDU_Observable
+                                                 *the_PDU_Observable, int fd)
+{
+    return 0;
+}
+
+P2_Session::~P2_Session()
+{
+}
+
+void P2_Session::recv_GDU(Z_GDU *z_pdu, int len)
+{
+    m_no_requests++;
+
+    Package *p = new Package(m_session, m_origin);
+
+    ThreadPoolPackage *m = new ThreadPoolPackage(p, this);
+    p->copy_filter(*m_package);
+    p->request() = yazpp_1::GDU(z_pdu);
+    m_my_thread->put(m);  
+}
+
+void P2_Session::failNotify()
+{
+    // TODO: send Package to signal "close"
+    m_delete_flag = true;
+    if (m_no_requests == 0)
+        delete this;
+    
+}
+
+void P2_Session::timeoutNotify()
+{
+    // TODO: send Package to signal "close"
+    m_delete_flag = true;
+    if (m_no_requests == 0)
+        delete this;
+}
+
+void P2_Session::connectNotify()
+{
+
+}
+
+class P2_Server : public yazpp_1::Z_Assoc {
+public:
+    ~P2_Server();
+    P2_Server(yazpp_1::IPDU_Observable *the_PDU_Observable,
+              ThreadPoolSocketObserver *m_my_thread,
+             const Package *package);
+private:
+    yazpp_1::IPDU_Observer* sessionNotify(
+        yazpp_1::IPDU_Observable *the_PDU_Observable,
+        int fd);
+    void recv_GDU(Z_GDU *apdu, int len);
+    
+    void failNotify();
+    void timeoutNotify();
+    void connectNotify();
+private:
+    ThreadPoolSocketObserver *m_my_thread;
+    const Package *m_package;
+};
+
+
+P2_Server::P2_Server(yazpp_1::IPDU_Observable *the_PDU_Observable,
+                     ThreadPoolSocketObserver *my_thread,
+                    const Package *package)
+    :  Z_Assoc(the_PDU_Observable)
+{
+    m_my_thread = my_thread;
+    m_package = package;
+
+}
+
+yazpp_1::IPDU_Observer *P2_Server::sessionNotify(yazpp_1::IPDU_Observable
+                                                *the_PDU_Observable, int fd)
+{
+    P2_Session *my = new P2_Session(the_PDU_Observable, m_my_thread,
+                                   m_package);
+    return my;
+}
+
+P2_Server::~P2_Server()
+{
+}
+
+void P2_Server::recv_GDU(Z_GDU *apdu, int len)
+{
+}
+
+void P2_Server::failNotify()
+{
+}
+
+void P2_Server::timeoutNotify()
+{
+}
+
+void P2_Server::connectNotify()
+{
+}
+
+FilterFrontendNet::FilterFrontendNet()
+{
+    m_no_threads = 5;
+    m_listen_address = "@:9001";
+    m_listen_duration = 0;
+}
+
+class My_Timer_Thread : public yazpp_1::ISocketObserver {
+private:
+    yazpp_1::ISocketObservable *m_obs;
+    int m_fd[2];
+    bool m_timeout;
+public:
+    My_Timer_Thread(yazpp_1::ISocketObservable *obs, int duration);
+    void socketNotify(int event);
+    bool timeout();
+};
+
+bool My_Timer_Thread::timeout()
+{
+    return m_timeout;
+}
+
+My_Timer_Thread::My_Timer_Thread(yazpp_1::ISocketObservable *obs,
+                                int duration) : 
+    m_obs(obs), m_timeout(false)
+{
+    pipe(m_fd);
+    obs->addObserver(m_fd[0], 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);
+    close(m_fd[0]);
+    close(m_fd[1]);
+}
+
+Package &FilterFrontendNet::process(Package &package) const {
+    yazpp_1::SocketManager mySocketManager;
+
+    My_Timer_Thread *tt = 0;
+    if (m_listen_duration)
+       tt = new My_Timer_Thread(&mySocketManager, m_listen_duration);
+
+    yazpp_1::PDU_Assoc *my_PDU_Assoc =
+       new yazpp_1::PDU_Assoc(&mySocketManager);
+    
+    ThreadPoolSocketObserver threadPool(&mySocketManager, m_no_threads);
+
+    P2_Server z(my_PDU_Assoc, &threadPool, &package);
+    z.server(m_listen_address.c_str());
+
+    while (mySocketManager.processEvent() > 0)
+    {
+       if (tt && tt->timeout())
+           break;
+    }
+    return package;
+}
+
+std::string &FilterFrontendNet::listen_address()
+{
+    return m_listen_address;
+}
+
+int &FilterFrontendNet::listen_duration()
+{
+    return m_listen_duration;
+}
+
diff --git a/src/filter_frontend_net.hpp b/src/filter_frontend_net.hpp
new file mode 100644 (file)
index 0000000..b30fabe
--- /dev/null
@@ -0,0 +1,33 @@
+
+#ifndef FILTER_FRONTEND_NET_HPP
+#define FILTER_FRONEND_NET_HPP
+
+#include <stdexcept>
+
+#include "filter.hpp"
+
+namespace yp2 {
+    class FilterFrontendNet : public yp2::Filter {
+    public:
+       FilterFrontendNet::FilterFrontendNet();
+       yp2::Package & process(yp2::Package & package) const;
+    private:
+        int m_no_threads;
+        std::string m_listen_address;
+        int m_listen_duration;
+    public:
+        /// set function - left val in assignment
+        std::string & listen_address();
+        int &listen_duration();
+    };
+}
+
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
index 0476ef2..ea68a14 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: p2_frontend.h,v 1.3 2005-10-13 10:00:02 adam Exp $
+/* $Id: p2_frontend.h,v 1.4 2005-10-13 20:06:45 adam Exp $
    Copyright (c) 1998-2005, Index Data.
 
 This file is part of the yaz-proxy.
@@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <vector>
 #include <string>
 
-#include "thread_pool_observer.h"
+#include "thread_pool_observer.hpp"
 #include <yaz++/z-assoc.h>
 #include <yaz++/pdu-assoc.h>
 #include <yaz++/gdu.h>
index 719aaf5..d49301c 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef PACKAGE_HPP
 #define PACKAGE_HPP
 
+#include <iostream>
 #include <stdexcept>
 #include <yaz++/gdu.h>
 
@@ -29,7 +30,13 @@ namespace yp2 {
         Package(yp2::Session &session, yp2::Origin &origin) 
             : m_session(session), m_origin(origin),
               m_filter(0), m_router(0), m_data(0)  {}
-        
+
+        Package & copy_filter(const Package &p) {
+            m_router = p.m_router;
+            m_filter = p.m_filter;
+            return *this;
+        }
+
         /// send Package to it's next Filter defined in Router
         Package & move() {
             m_filter = m_router->move(m_filter, this);
@@ -82,6 +89,14 @@ namespace yp2 {
             m_router = &router;
             return *this;
         }
+
+        yazpp_1::GDU &request() {
+            return m_request_gdu;
+        }
+
+        yazpp_1::GDU &response() {
+            return m_response_gdu;
+        }
                 
     private:
         Session m_session;
diff --git a/src/session.cpp b/src/session.cpp
new file mode 100644 (file)
index 0000000..0977505
--- /dev/null
@@ -0,0 +1,19 @@
+
+#include <stdexcept>
+
+#include "session.hpp"
+#include <boost/thread/mutex.hpp>
+
+#include "config.hpp"
+
+// defining and initializing static members
+boost::mutex yp2::Session::m_mutex;
+unsigned long int yp2::Session::m_global_id = 0;
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
index 9667a17..52c2d3e 100644 (file)
@@ -61,11 +61,6 @@ namespace yp2 {
     
 }
 
-// defining and initializing static members
-boost::mutex yp2::Session::m_mutex;
-unsigned long int yp2::Session::m_global_id = 0;
-
-
 #endif
 /*
  * Local variables:
diff --git a/src/test_filter_frontend_net.cpp b/src/test_filter_frontend_net.cpp
new file mode 100644 (file)
index 0000000..f5ea15a
--- /dev/null
@@ -0,0 +1,108 @@
+
+#include "config.hpp"
+#include <iostream>
+#include <stdexcept>
+
+#include "router.hpp"
+#include "session.hpp"
+#include "package.hpp"
+#include "filter_frontend_net.hpp"
+
+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+
+using namespace boost::unit_test;
+
+class FilterInit: public yp2::Filter {
+public:
+    yp2::Package & process(yp2::Package & package) const {
+        ODR odr = odr_createmem(ODR_ENCODE);
+        Z_APDU *apdu = zget_APDU(odr, Z_APDU_initResponse);
+
+        apdu->u.initResponse->implementationName = "YP2/YAZ";
+
+        package.response() = apdu;
+        odr_destroy(odr);
+       return package.move();
+    };
+};
+
+
+BOOST_AUTO_TEST_CASE( test_filter_frontend_net_1 )
+{
+    try 
+    {
+        {
+            yp2::FilterFrontendNet nf;
+        }
+        BOOST_CHECK(true);
+    }
+    catch ( ... ) {
+        BOOST_CHECK (false);
+    }
+}
+
+BOOST_AUTO_TEST_CASE( test_filter_frontend_net_2 )
+{
+    try 
+    {
+        {
+           yp2::RouterChain router;
+
+            FilterInit tf;
+
+           router.rule(tf);
+
+            yp2::Session session;
+            yp2::Origin origin;
+           yp2::Package pack_in(session, origin);
+           
+           pack_in.router(router).move(); 
+
+            yazpp_1::GDU *gdu = &pack_in.response();
+
+            BOOST_CHECK_EQUAL(gdu->get()->which, Z_GDU_Z3950);
+            BOOST_CHECK_EQUAL(gdu->get()->u.z3950->which, Z_APDU_initResponse);
+        }
+        BOOST_CHECK(true);
+    }
+    catch ( ... ) {
+        BOOST_CHECK (false);
+    }
+}
+
+BOOST_AUTO_TEST_CASE( test_filter_frontend_net_3 )
+{
+    try 
+    {
+        {
+           yp2::RouterChain router;
+
+            yp2::FilterFrontendNet filter_front;
+            filter_front.listen_address() = "unix:socket";
+            filter_front.listen_duration() = 2;  // listen a short time only
+           router.rule(filter_front);
+
+            FilterInit filter_init;
+           router.rule(filter_init);
+
+            yp2::Session session;
+            yp2::Origin origin;
+           yp2::Package pack_in(session, origin);
+           
+           pack_in.router(router).move(); 
+        }
+        BOOST_CHECK(true);
+    }
+    catch ( ... ) {
+        BOOST_CHECK (false);
+    }
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
index 8086d2c..532aefd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: test_thread_pool_observer.cpp,v 1.3 2005-10-12 23:30:43 adam Exp $
+/* $Id: test_thread_pool_observer.cpp,v 1.4 2005-10-13 20:06:45 adam Exp $
    Copyright (c) 1998-2005, Index Data.
 
 This file is part of the yaz-proxy.
@@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <yaz++/pdu-assoc.h>
 #include <yaz++/socket-manager.h>
 #include <yaz/log.h>
-#include "thread_pool_observer.h"
+#include "thread_pool_observer.hpp"
 
 #define BOOST_AUTO_TEST_MAIN
 #include <boost/test/auto_unit_test.hpp>
index b66be7e..de0cf63 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: thread_pool_observer.cpp,v 1.3 2005-10-12 23:30:43 adam Exp $
+/* $Id: thread_pool_observer.cpp,v 1.4 2005-10-13 20:06:45 adam Exp $
    Copyright (c) 1998-2005, Index Data.
 
 This file is part of the yaz-proxy.
@@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <yaz/log.h>
 
 #include "config.hpp"
-#include "thread_pool_observer.h"
+#include "thread_pool_observer.hpp"
 
 using namespace yazpp_1;
 
diff --git a/src/thread_pool_observer.h b/src/thread_pool_observer.h
deleted file mode 100644 (file)
index 34e23a0..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $Id: thread_pool_observer.h,v 1.2 2005-10-12 23:30:43 adam Exp $
-   Copyright (c) 1998-2005, Index Data.
-
-This file is part of the yaz-proxy.
-
-YAZ proxy is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
-
-YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with YAZ proxy; see the file LICENSE.  If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
- */
-
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition.hpp>
-
-#include <unistd.h>
-#include <ctype.h>
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <deque>
-#include <yaz++/socket-observer.h>
-#include <yaz/yconfig.h>
-
-class IThreadPoolMsg {
-public:
-    virtual IThreadPoolMsg *handle() = 0;
-    virtual void result() = 0;
-    virtual ~IThreadPoolMsg();
-};
-
-class ThreadPoolSocketObserver : public yazpp_1::ISocketObserver {
- public:
-    ThreadPoolSocketObserver(yazpp_1::ISocketObservable *obs, int no_threads);
-    virtual ~ThreadPoolSocketObserver();
-    void socketNotify(int event);
-    void put(IThreadPoolMsg *m);
-    IThreadPoolMsg *get();
-    void run(void *p);
-    int m_fd[2];
-private:
-    yazpp_1::ISocketObservable *m_SocketObservable;
-    int m_no_threads;
-    boost::thread_group m_thrds;
-
-    std::deque<IThreadPoolMsg *> m_input;
-    std::deque<IThreadPoolMsg *> m_output;
-
-    boost::mutex m_mutex_input_data;
-    boost::condition m_cond_input_data;
-    boost::mutex m_mutex_output_data;
-    bool m_stop_flag;
-};
-
-/*
- * Local variables:
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- * vim: shiftwidth=4 tabstop=8 expandtab
- */
-
diff --git a/src/thread_pool_observer.hpp b/src/thread_pool_observer.hpp
new file mode 100644 (file)
index 0000000..0ff7a50
--- /dev/null
@@ -0,0 +1,74 @@
+/* $Id: thread_pool_observer.hpp,v 1.1 2005-10-13 20:06:45 adam Exp $
+   Copyright (c) 1998-2005, Index Data.
+
+This file is part of the yaz-proxy.
+
+YAZ proxy is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+YAZ proxy is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with YAZ proxy; see the file LICENSE.  If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+ */
+
+#ifndef YP2_THREAD_POOL_OBSERVER_HPP
+#define YP2_THREAD_POOL_OBSERVER_HPP
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+#include <unistd.h>
+#include <ctype.h>
+
+#include <deque>
+#include <yaz++/socket-observer.h>
+#include <yaz/yconfig.h>
+
+class IThreadPoolMsg {
+public:
+    virtual IThreadPoolMsg *handle() = 0;
+    virtual void result() = 0;
+    virtual ~IThreadPoolMsg();
+};
+
+class ThreadPoolSocketObserver : public yazpp_1::ISocketObserver {
+ public:
+    ThreadPoolSocketObserver(yazpp_1::ISocketObservable *obs, int no_threads);
+    virtual ~ThreadPoolSocketObserver();
+    void socketNotify(int event);
+    void put(IThreadPoolMsg *m);
+    IThreadPoolMsg *get();
+    void run(void *p);
+    int m_fd[2];
+private:
+    yazpp_1::ISocketObservable *m_SocketObservable;
+    int m_no_threads;
+    boost::thread_group m_thrds;
+
+    std::deque<IThreadPoolMsg *> m_input;
+    std::deque<IThreadPoolMsg *> m_output;
+
+    boost::mutex m_mutex_input_data;
+    boost::condition m_cond_input_data;
+    boost::mutex m_mutex_output_data;
+    bool m_stop_flag;
+};
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+