Added safe HttpMsg pointer wrapper that locks and unlocks the message.

This class will not be needed if we switch to refcounting HttpMsg. Meanwhile, it allows to pass message pointers in AsyncCalls and avoid auto_ptr<> in exception-sensitive code.

---------

I am considering making the HttpMsgPointerT::lock() and unlock() methods protected because it would be difficult for the caller to use them correctly and because it is probably not necessary for the caller to use them at all.

Thank you,

Alex.
Added safe HttpMsg pointer wrapper that locks and unlocks the message.

This class will not be needed if we switch to refcounting HttpMsg. Meanwhile,
it allows to pass message pointers in AsyncCalls and avoid auto_ptr<> in
exception-sensitive code.

=== modified file 'src/HttpMsg.h'
--- src/HttpMsg.h	2010-08-19 00:12:43 +0000
+++ src/HttpMsg.h	2010-08-30 22:06:01 +0000
@@ -167,4 +167,41 @@
 #define HTTPMSGUNLOCK(a) if(a){(a)->_unlock();(a)=NULL;}
 #define HTTPMSGLOCK(a) (a)->_lock()
 
+// TODO: replace HTTPMSGLOCK with general RefCounting and delete this class
+/// safe HttpMsg pointer wrapper that locks and unlocks the message
+template <class Msg>
+class HttpMsgPointerT
+{
+public:
+    HttpMsgPointerT(): msg(NULL) {}
+    explicit HttpMsgPointerT(Msg *m): msg(m) { lock(); }
+    virtual ~HttpMsgPointerT() { unlock(); }
+
+    HttpMsgPointerT(const HttpMsgPointerT &p): msg(p.msg) { lock(); }
+    HttpMsgPointerT &operator =(const HttpMsgPointerT &p)
+        { if (msg != p.msg) { unlock(); msg = p.msg; lock(); } return *this; }
+
+    Msg &operator *() { return *msg; }
+    const Msg &operator *() const { return *msg; }
+    Msg *operator ->() { return msg; }
+    const Msg *operator ->() const { return msg; }
+    operator Msg *() { return msg; }
+    operator const Msg *() const { return msg; }
+    // add more as needed
+
+    void lock() { if (msg) HTTPMSGLOCK(msg); } ///< prevent msg destruction
+    void unlock() { HTTPMSGUNLOCK(msg); } ///< allows/causes msg destruction
+
+private:
+    Msg *msg;
+};
+
+/// convenience wrapper to create HttpMsgPointerT<> object based on msg type
+template <class Msg>
+inline
+HttpMsgPointerT<Msg> HttpMsgPointer(Msg *msg)
+{
+    return HttpMsgPointerT<Msg>(msg);
+}
+
 #endif /* SQUID_HTTPMSG_H */

Reply via email to