[packages/squid] - added libecap 1.0 patch - http://www.squid-cache.org/mail-archive/squid-dev/201310/0182.html - rel

baggins baggins at pld-linux.org
Sat Feb 1 21:08:07 CET 2014


commit 98801e83e6afe1a6fa26100f8a10cbb22a28ac12
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Sat Feb 1 21:07:31 2014 +0100

    - added libecap 1.0 patch - http://www.squid-cache.org/mail-archive/squid-dev/201310/0182.html
    - rel 2

 ecap-1p0-t2.patch | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 squid.spec        |   4 +-
 2 files changed, 515 insertions(+), 1 deletion(-)
---
diff --git a/squid.spec b/squid.spec
index 4f74b7a..54b4063 100644
--- a/squid.spec
+++ b/squid.spec
@@ -17,7 +17,7 @@ Summary(uk.UTF-8):	Squid - кеш об'єктів Internet
 Summary(zh_CN.UTF-8):	SQUID 高速缓冲代理服务器
 Name:		squid
 Version:	3.3.11
-Release:	1
+Release:	2
 Epoch:		7
 License:	GPL v2
 Group:		Networking/Daemons
@@ -45,6 +45,7 @@ Patch7:		squidv3-vary-cache-1.patch
 # http://www.squid-cache.org/mail-archive/squid-dev/201207/att-0177/squidv3-vary-headers-shm-hack.patch
 Patch8:		squidv3-vary-headers-shm-hack.patch
 Patch9:		perl-5.18.patch
+Patch10:	ecap-1p0-t2.patch
 URL:		http://www.squid-cache.org/
 BuildRequires:	autoconf
 BuildRequires:	automake
@@ -624,6 +625,7 @@ Ten pakiet zawiera skrypty perlowe i dodatkowe programy dla Squida.
 %patch7 -p1
 %patch8 -p1
 %patch9 -p1
+%patch10 -p0
 
 %{__sed} -i -e '1s#!.*bin/perl#!%{__perl}#' {contrib,scripts}/*.pl
 
diff --git a/ecap-1p0-t2.patch b/ecap-1p0-t2.patch
new file mode 100644
index 0000000..85e149e
--- /dev/null
+++ b/ecap-1p0-t2.patch
@@ -0,0 +1,512 @@
+Support libecap v1.0, allowing asynchronous adapters and eCAP version checks.
+
+After these changes, Squid can support eCAP adapters built with libecap v1.0,
+but stops supporting adapters built with earlier libecap versions (due to API
+changes). The new libecap version allows Squid to better check the version of
+the eCAP adapter being loaded as well as the version of the eCAP library being
+used. This should help with migration to libecap v1.0.
+
+
+Expose [running] main event loop as a global so that modules can add engines.
+
+=== modified file 'configure.ac'
+--- configure.ac	2013-07-09 11:15:51 +0000
++++ configure.ac	2013-09-12 23:08:18 +0000
+@@ -1035,10 +1035,10 @@
+ 
+   if test -n "$PKG_CONFIG"; then
+     dnl eCAP support requires libecap.
+-    dnl This Squid supports libecap v0.2.x.
++    dnl This Squid supports libecap v1.0.x.
+     dnl Use EXT_ prefix to distinguish external libecap (that we check for
+     dnl here) from our own convenience ecap library in Makefiles.
+-    PKG_CHECK_MODULES([EXT_LIBECAP],[libecap >= 0.2.0 libecap < 0.3])
++    PKG_CHECK_MODULES([EXT_LIBECAP],[libecap >= 1.0 libecap < 1.1])
+   else
+     AC_MSG_NOTICE([eCAP support requires pkg-config to verify the correct library version. Trouble may follow.])
+   fi
+
+=== modified file 'src/EventLoop.cc'
+--- src/EventLoop.cc	2013-02-17 02:09:16 +0000
++++ src/EventLoop.cc	2013-09-16 00:07:51 +0000
+@@ -37,6 +37,8 @@
+ #include "base/AsyncCallQueue.h"
+ #include "SquidTime.h"
+ 
++EventLoop *EventLoop::Running = NULL;
++
+ EventLoop::EventLoop() : errcount(0), last_loop(false), timeService(NULL),
+         primaryEngine(NULL),
+         loop_delay(EVENT_LOOP_TIMEOUT),
+@@ -96,7 +98,12 @@
+ {
+     prepareToRun();
+ 
++    assert(!Running);
++    Running = this;
++
+     while (!runOnce());
++
++    Running = NULL;
+ }
+ 
+ bool
+
+=== modified file 'src/EventLoop.h'
+--- src/EventLoop.h	2013-05-04 11:50:26 +0000
++++ src/EventLoop.h	2013-09-16 00:07:51 +0000
+@@ -89,6 +89,10 @@
+ 
+     int errcount;
+ 
++    /// the [main program] loop running now; may be nil
++    /// for simplicity, we assume there are no concurrent loops
++    static EventLoop *Running;
++
+ private:
+     /** setup state variables prior to running */
+     void prepareToRun();
+
+=== modified file 'src/adaptation/ecap/Host.cc'
+--- src/adaptation/ecap/Host.cc	2012-08-28 13:00:30 +0000
++++ src/adaptation/ecap/Host.cc	2013-09-16 18:04:34 +0000
+@@ -70,11 +70,55 @@
+     os << PACKAGE_NAME << " v" << PACKAGE_VERSION;
+ }
+ 
++/// Strips libecap version components not affecting compatibility decisions.
++static std::string
++EssentialVersion(const std::string &raw)
++{
++    // all libecap x.y.* releases are supposed to be compatible so we strip
++    // everything after the second period
++    const std::string::size_type minorPos = raw.find('.');
++    const std::string::size_type microPos = minorPos == std::string::npos ?
++        std::string::npos : raw.find('.', minorPos+1);
++    return raw.substr(0, microPos); // becomes raw if microPos is npos
++}
++
++/// If "their" libecap version is not compatible with what Squid has been built
++/// with, then complain and return false.
++static bool
++SupportedVersion(const char *vTheir, const std::string &them)
++{
++    if (!vTheir || !*vTheir) {
++        debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
++               " with libecap prior to v1.0.");
++        return false;
++    }
++
++    // we support what we are built with
++    const std::string vSupported(LIBECAP_VERSION);
++    debugs(93, 2, them << " with libecap v" << vTheir << "; us: v" << vSupported);
++
++    if (EssentialVersion(vTheir) == EssentialVersion(vSupported))
++        return true; // their version is supported
++
++    debugs(93, DBG_CRITICAL, "ERROR: Cannot use " << them <<
++           " with libecap v" << vTheir <<
++           ": incompatible with supported libecap v" << vSupported);
++    return false;
++}
++
+ void
+-Adaptation::Ecap::Host::noteService(const libecap::weak_ptr<libecap::adapter::Service> &weak)
++Adaptation::Ecap::Host::noteVersionedService(const char *vGiven, const libecap::weak_ptr<libecap::adapter::Service> &weak)
+ {
+-    Must(!weak.expired());
+-    RegisterAdapterService(weak.lock());
++    /*
++     * Check that libecap used to build the service is compatible with ours.
++     * This has to be done using vGiven string and not Service object itself
++     * because dereferencing a Service pointer coming from an unsupported
++     * version is unsafe.
++     */
++    if (SupportedVersion(vGiven, "eCAP service built")) {
++        Must(!weak.expired());
++        RegisterAdapterService(weak.lock());
++    }
+ }
+ 
+ static int
+@@ -126,7 +170,8 @@
+ void
+ Adaptation::Ecap::Host::Register()
+ {
+-    if (!TheHost) {
++    if (!TheHost && SupportedVersion(libecap::VersionString(),
++                                     "Squid executable dynamically linked")) {
+         TheHost.reset(new Adaptation::Ecap::Host);
+         libecap::RegisterHost(TheHost);
+     }
+
+=== modified file 'src/adaptation/ecap/Host.h'
+--- src/adaptation/ecap/Host.h	2012-10-04 11:10:17 +0000
++++ src/adaptation/ecap/Host.h	2013-09-16 18:04:34 +0000
+@@ -19,7 +19,7 @@
+     /* libecap::host::Host API */
+     virtual std::string uri() const; // unique across all vendors
+     virtual void describe(std::ostream &os) const; // free-format info
+-    virtual void noteService(const libecap::weak_ptr<libecap::adapter::Service> &s);
++    virtual void noteVersionedService(const char *libEcapVersion, const libecap::weak_ptr<libecap::adapter::Service> &s);
+     virtual std::ostream *openDebug(libecap::LogVerbosity lv);
+     virtual void closeDebug(std::ostream *debug);
+     typedef libecap::shared_ptr<libecap::Message> MessagePtr;
+
+=== modified file 'src/adaptation/ecap/ServiceRep.cc'
+--- src/adaptation/ecap/ServiceRep.cc	2012-08-28 13:00:30 +0000
++++ src/adaptation/ecap/ServiceRep.cc	2013-09-16 18:04:34 +0000
+@@ -2,20 +2,29 @@
+  * DEBUG: section 93    eCAP Interface
+  */
+ #include "squid.h"
++#include "adaptation/ecap/Config.h"
++#include "adaptation/ecap/Host.h"
++#include "adaptation/ecap/ServiceRep.h"
++#include "adaptation/ecap/XactionRep.h"
++#include "AsyncEngine.h"
++#include "base/TextException.h"
+ #include "Debug.h"
+-#include <list>
++#include "EventLoop.h"
+ #include <libecap/adapter/service.h>
+ #include <libecap/common/options.h>
+ #include <libecap/common/name.h>
+ #include <libecap/common/named_values.h>
+-#include "adaptation/ecap/Config.h"
+-#include "adaptation/ecap/Host.h"
+-#include "adaptation/ecap/ServiceRep.h"
+-#include "adaptation/ecap/XactionRep.h"
+-#include "base/TextException.h"
++#if HAVE_LIMITS
++#include <limits>
++#endif
++#include <map>
+ 
+-// configured eCAP service wrappers
+-static std::list<Adaptation::Ecap::ServiceRep::AdapterService> TheServices;
++/// libecap::adapter::services indexed by their URI
++typedef std::map<std::string, Adaptation::Ecap::ServiceRep::AdapterService> AdapterServices;
++/// all loaded services
++static AdapterServices TheServices;
++/// configured services producing async transactions
++static AdapterServices AsyncServices;
+ 
+ namespace Adaptation
+ {
+@@ -39,6 +48,17 @@
+     const Master &master; ///< the configuration being wrapped
+ };
+ 
++/// manages async eCAP transactions
++class Engine: public AsyncEngine
++{
++public:
++    /* AsyncEngine API */
++    virtual int checkEvents(int timeout);
++
++private:
++    void kickAsyncServices(timeval &timeout);
++};
++
+ } // namespace Ecap
+ } // namespace Adaptation
+ 
+@@ -76,6 +96,55 @@
+         visitor.visit(Name(i->first), Area::FromTempString(i->second));
+ }
+ 
++/* Adaptation::Ecap::Engine */
++
++int
++Adaptation::Ecap::Engine::checkEvents(int)
++{
++    // Start with the default I/O loop timeout, convert from milliseconds.
++    static const struct timeval maxTimeout {
++        EVENT_LOOP_TIMEOUT/1000, // seconds
++        (EVENT_LOOP_TIMEOUT % 1000)*1000 
++    }; // microseconds
++    struct timeval timeout = maxTimeout;
++
++    kickAsyncServices(timeout);
++    if (timeout.tv_sec == maxTimeout.tv_sec && timeout.tv_usec == maxTimeout.tv_usec)
++        return EVENT_IDLE;
++
++    debugs(93, 7, "timeout: " << timeout.tv_sec << "s+" << timeout.tv_usec << "us");
++
++    // convert back to milliseconds, avoiding int overflows
++    if (timeout.tv_sec >= std::numeric_limits<int>::max()/1000 - 1000)
++        return std::numeric_limits<int>::max();
++    else
++        return timeout.tv_sec*1000 + timeout.tv_usec/1000;
++}
++
++/// resumes async transactions (if any) and returns true if they set a timeout
++void
++Adaptation::Ecap::Engine::kickAsyncServices(timeval &timeout)
++{
++    if (AsyncServices.empty())
++        return;
++
++    debugs(93, 3, "async services: " << AsyncServices.size());
++
++    // Activate waiting async transactions, if any.
++    typedef AdapterServices::iterator ASI;
++    for (ASI s = AsyncServices.begin(); s != AsyncServices.end(); ++s) {
++        assert(s->second);
++        s->second->resume(); // may call Ecap::Xaction::resume()
++    }
++
++    // Give services a chance to decrease the default timeout.
++    for (ASI s = AsyncServices.begin(); s != AsyncServices.end(); ++s) {
++        s->second->suspend(timeout);
++    }
++}
++
++/* Adaptation::Ecap::ServiceRep */
++
+ Adaptation::Ecap::ServiceRep::ServiceRep(const ServiceConfigPointer &cfg):
+         /*AsyncJob("Adaptation::Ecap::ServiceRep"),*/ Adaptation::Service(cfg),
+         isDetached(false)
+@@ -123,6 +192,11 @@
+ 
+     debugs(93,DBG_IMPORTANT, "Starting eCAP service: " << theService->uri());
+     theService->start();
++
++    if (theService->makesAsyncXactions()) {
++        AsyncServices[theService->uri()] = theService;
++        debugs(93, 5, "asyncs: " << AsyncServices.size());
++    }
+ }
+ 
+ /// handles failures while configuring or starting an eCAP service;
+@@ -168,6 +242,16 @@
+         HttpRequest *cause)
+ {
+     Must(up());
++
++    // register now because (a) we need EventLoop::Running and (b) we do not
++    // want to add more main loop overheads unless an async service is used.
++    static AsyncEngine *TheEngine = NULL;
++    if (AsyncServices.size() && !TheEngine && EventLoop::Running) {
++        TheEngine = new Engine;
++        EventLoop::Running->registerEngine(TheEngine);
++        debugs(93, 3, "asyncs: " << AsyncServices.size() << ' ' << TheEngine);
++    }
++
+     XactionRep *rep = new XactionRep(virgin, cause, Pointer(this));
+     XactionRep::AdapterXaction x(theService->makeXaction(rep));
+     rep->master(x);
+@@ -210,11 +294,10 @@
+ Adaptation::Ecap::ServiceRep::AdapterService
+ Adaptation::Ecap::FindAdapterService(const String& serviceUri)
+ {
+-    typedef std::list<ServiceRep::AdapterService>::const_iterator ASCI;
+-    for (ASCI s = TheServices.begin(); s != TheServices.end(); ++s) {
+-        Must(*s);
+-        if (serviceUri == (*s)->uri().c_str())
+-            return *s;
++    AdapterServices::const_iterator pos = TheServices.find(serviceUri.termedBuf());
++    if (pos != TheServices.end()) {
++        Must(pos->second);
++        return pos->second;
+     }
+     return ServiceRep::AdapterService();
+ }
+@@ -222,30 +305,18 @@
+ void
+ Adaptation::Ecap::RegisterAdapterService(const Adaptation::Ecap::ServiceRep::AdapterService& adapterService)
+ {
+-    typedef std::list<ServiceRep::AdapterService>::iterator ASI;
+-    for (ASI s = TheServices.begin(); s != TheServices.end(); ++s) {
+-        Must(*s);
+-        if (adapterService->uri() == (*s)->uri()) {
+-            *s = adapterService;
+-            debugs(93, 3, "updated eCAP module service: " <<
+-                   adapterService->uri());
+-            return;
+-        }
+-    }
+-    TheServices.push_back(adapterService);
+-    debugs(93, 3, "registered eCAP module service: " << adapterService->uri());
++    TheServices[adapterService->uri()] = adapterService; // may update old one
++    debugs(93, 3, "stored eCAP module service: " << adapterService->uri());
++    // We do not update AsyncServices here in case they are not configured.
+ }
+ 
+ void
+ Adaptation::Ecap::UnregisterAdapterService(const String& serviceUri)
+ {
+-    typedef std::list<ServiceRep::AdapterService>::iterator ASI;
+-    for (ASI s = TheServices.begin(); s != TheServices.end(); ++s) {
+-        if (serviceUri == (*s)->uri().c_str()) {
+-            TheServices.erase(s);
+-            debugs(93, 3, "unregistered eCAP module service: " << serviceUri);
+-            return;
+-        }
++    if (TheServices.erase(serviceUri.termedBuf())) {
++        debugs(93, 3, "unregistered eCAP module service: " << serviceUri);
++        AsyncServices.erase(serviceUri.termedBuf()); // no-op for non-async
++        return;
+     }
+     debugs(93, 3, "failed to unregister eCAP module service: " << serviceUri);
+ }
+@@ -253,16 +324,16 @@
+ void
+ Adaptation::Ecap::CheckUnusedAdapterServices(const Adaptation::Services& cfgs)
+ {
+-    typedef std::list<ServiceRep::AdapterService>::const_iterator ASCI;
++    typedef AdapterServices::const_iterator ASCI;
+     for (ASCI loaded = TheServices.begin(); loaded != TheServices.end();
+             ++loaded) {
+         bool found = false;
+         for (Services::const_iterator cfged = cfgs.begin();
+                 cfged != cfgs.end() && !found; ++cfged) {
+-            found = (*cfged)->cfg().uri == (*loaded)->uri().c_str();
++            found = (*cfged)->cfg().uri == loaded->second->uri().c_str();
+         }
+         if (!found)
+             debugs(93, DBG_IMPORTANT, "Warning: loaded eCAP service has no matching " <<
+-                   "ecap_service config option: " << (*loaded)->uri());
++                   "ecap_service config option: " << loaded->second->uri());
+     }
+ }
+
+=== modified file 'src/adaptation/ecap/XactionRep.cc'
+--- src/adaptation/ecap/XactionRep.cc	2013-06-03 14:05:16 +0000
++++ src/adaptation/ecap/XactionRep.cc	2013-09-23 16:22:57 +0000
+@@ -2,19 +2,20 @@
+  * DEBUG: section 93    eCAP Interface
+  */
+ #include "squid.h"
++#include "adaptation/Answer.h"
++#include "adaptation/ecap/XactionRep.h"
++#include "adaptation/ecap/Config.h"
++#include "adaptation/Initiator.h"
++#include "base/AsyncJobCalls.h"
++#include "base/TextException.h"
++#include "HttpRequest.h"
++#include "HttpReply.h"
++#include "SquidTime.h"
+ #include <libecap/common/area.h>
+ #include <libecap/common/delay.h>
+ #include <libecap/common/named_values.h>
+ #include <libecap/common/names.h>
+ #include <libecap/adapter/xaction.h>
+-#include "HttpRequest.h"
+-#include "HttpReply.h"
+-#include "SquidTime.h"
+-#include "adaptation/Answer.h"
+-#include "adaptation/ecap/XactionRep.h"
+-#include "adaptation/ecap/Config.h"
+-#include "adaptation/Initiator.h"
+-#include "base/TextException.h"
+ 
+ CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
+ 
+@@ -273,6 +274,25 @@
+     Adaptation::Initiate::swanSong();
+ }
+ 
++void
++Adaptation::Ecap::XactionRep::resume()
++{
++    // go async to gain exception protection and done()-based job destruction
++    typedef NullaryMemFunT<Adaptation::Ecap::XactionRep> Dialer;
++    AsyncCall::Pointer call = asyncCall(93, 5, "Adaptation::Ecap::XactionRep::doResume",
++                                        Dialer(this, &Adaptation::Ecap::XactionRep::doResume));
++    ScheduleCallHere(call);
++}
++
++/// the guts of libecap::host::Xaction::resume() API implementation
++/// which just goes async in Adaptation::Ecap::XactionRep::resume().
++void
++Adaptation::Ecap::XactionRep::doResume()
++{
++    Must(theMaster);
++    theMaster->resume();
++}
++
+ libecap::Message &
+ Adaptation::Ecap::XactionRep::virgin()
+ {
+@@ -595,12 +615,6 @@
+     mustStop("adaptationAborted");
+ }
+ 
+-bool
+-Adaptation::Ecap::XactionRep::callable() const
+-{
+-    return !done();
+-}
+-
+ void
+ Adaptation::Ecap::XactionRep::noteMoreBodySpaceAvailable(RefCount<BodyPipe> bp)
+ {
+
+=== modified file 'src/adaptation/ecap/XactionRep.h'
+--- src/adaptation/ecap/XactionRep.h	2012-10-04 11:10:17 +0000
++++ src/adaptation/ecap/XactionRep.h	2013-09-23 16:22:57 +0000
+@@ -44,6 +44,7 @@
+     virtual void blockVirgin();
+     virtual void adaptationDelayed(const libecap::Delay &);
+     virtual void adaptationAborted();
++    virtual void resume();
+     virtual void vbDiscard();
+     virtual void vbMake();
+     virtual void vbStopMaking();
+@@ -53,9 +54,6 @@
+     virtual void noteAbContentDone(bool atEnd);
+     virtual void noteAbContentAvailable();
+ 
+-    // libecap::Callable API, via libecap::host::Xaction
+-    virtual bool callable() const;
+-
+     // BodyProducer API
+     virtual void noteMoreBodySpaceAvailable(RefCount<BodyPipe> bp);
+     virtual void noteBodyConsumerAborted(RefCount<BodyPipe> bp);
+@@ -97,6 +95,8 @@
+     /// Return the adaptation meta headers and their values
+     void visitEachMetaHeader(libecap::NamedValueVisitor &visitor) const;
+ 
++    void doResume();
++
+ private:
+     AdapterXaction theMaster; // the actual adaptation xaction we represent
+     Adaptation::ServicePointer theService; ///< xaction's adaptation service
+
+=== modified file 'src/main.cc'
+--- src/main.cc	2013-06-07 04:35:25 +0000
++++ src/main.cc	2013-09-16 00:12:40 +0000
+@@ -225,17 +225,15 @@
+ {
+ 
+ public:
+-    SignalEngine(EventLoop &evtLoop) : loop(evtLoop) {}
+     virtual int checkEvents(int timeout);
+ 
+ private:
+-    static void StopEventLoop(void * data) {
+-        static_cast<SignalEngine *>(data)->loop.stop();
++    static void StopEventLoop(void *) {
++        if (EventLoop::Running)
++            EventLoop::Running->stop();
+     }
+ 
+     void doShutdown(time_t wait);
+-
+-    EventLoop &loop;
+ };
+ 
+ int
+@@ -1506,7 +1504,7 @@
+     /* main loop */
+     EventLoop mainLoop;
+ 
+-    SignalEngine signalEngine(mainLoop);
++    SignalEngine signalEngine;
+ 
+     mainLoop.registerEngine(&signalEngine);
+ 
+
+
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/squid.git/commitdiff/98801e83e6afe1a6fa26100f8a10cbb22a28ac12



More information about the pld-cvs-commit mailing list