// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_BASE_COMPLETION_CALLBACK_H__ #define NET_BASE_COMPLETION_CALLBACK_H__ #include "base/task.h" #include "net/base/io_buffer.h" namespace net { // A callback specialization that takes a single int parameter. Usually this // is used to report a byte count or network error code. typedef Callback1::Type CompletionCallback; // Used to implement a CompletionCallback. template class CompletionCallbackImpl : public CallbackImpl< T, void (T::*)(int), Tuple1 > { public: CompletionCallbackImpl(T* obj, void (T::* meth)(int)) : CallbackImpl< T, void (T::*)(int), Tuple1 >::CallbackImpl(obj, meth) { } }; // CancelableCompletionCallback is used for completion callbacks // which may outlive the target for the method dispatch. In such a case, the // provider of the callback calls Cancel() to mark the callback as // "canceled". When the canceled callback is eventually run it does nothing // other than to decrement the refcount to 0 and free the memory. template class CancelableCompletionCallback : public CompletionCallbackImpl, public base::RefCounted > { public: CancelableCompletionCallback(T* obj, void (T::* meth)(int)) : CompletionCallbackImpl(obj, meth), is_canceled_(false) { } void Cancel() { is_canceled_ = true; } // Attaches the given buffer to this callback so it is valid until the // operation completes. TODO(rvargas): This is a temporal fix for bug 5325 // while I send IOBuffer to the lower layers of code. void UseBuffer(net::IOBuffer* buffer) { DCHECK(!buffer_.get()); buffer_ = buffer; } // The callback is not expected anymore so release the buffer. void ReleaseBuffer() { DCHECK(buffer_.get()); buffer_ = NULL; } virtual void RunWithParams(const Tuple1& params) { if (is_canceled_) { CancelableCompletionCallback::ReleaseBuffer(); base::RefCounted >::Release(); } else { CompletionCallbackImpl::RunWithParams(params); } } private: scoped_refptr buffer_; bool is_canceled_; }; } // namespace net #endif // NET_BASE_COMPLETION_CALLBACK_H__