[ofw] NDv2 provider patch
Hefty, Sean
sean.hefty at intel.com
Mon Jul 26 10:30:19 PDT 2010
Responses are separated based on classes as I review them.
> +template<class T>
> +class auto_ref
> {
> + T* m_pObj;
> +
> public:
> + auto_ref( T* pObj ) :
> + m_pObj( pObj )
> + {
> + if( m_pObj != NULL ){
> + m_pObj->AddRef();
> + }
> + }
> + auto_ref( const auto_ref& r ) :
> + m_pObj( r.m_pObj )
> + {
> + if( m_pObj != NULL ){
The syntax should be:
if (no space here) {
for(no space here) {
while(no space here) {
"( " and " )" are not used in normal writing, so should not be done in code. It leads to inconsistencies as visible in the code below. There should be a space before the '{'.
> + m_pObj->AddRef();
Didn't you mean AddRef( )? ;)
> + }
> + }
> + ~auto_ref()
> + {
> + if( m_pObj != NULL ){
> + m_pObj->Release();
> + }
> + }
> +
> + T* operator ->() const { return m_pObj; }
> + T* detach(){ T* tmp = m_pObj; m_pObj = NULL; return tmp; }
> + T* get() const { return m_pObj; }
> + T** ref(){ return &m_pObj; }
> + VOID** ppvObj(){ return reinterpret_cast<void**>(ref()); }
> +
> + auto_ref& operator =( T* pObj )
> + {
> + if( m_pObj != NULL )
> + {
> + m_pObj->Release();
> + }
> + m_pObj = pObj;
> + return *this;
> + }
> +
> + auto_ref& operator =( const auto_ref& r )
> + {
> + if( m_pObj != NULL )
> + {
> + m_pObj->Release();
> + }
> + m_pObj = r.get();
> + if( m_pObj != NULL )
> + {
> + m_pObj->AddRef();
> + }
> + return *this;
> + }
> +
> +};
auto-reference obscurity...
> +
> +
> +class CNDBase
> +{
> + static volatile LONG m_nObj;
> + volatile LONG m_nRef;
> +
> +protected:
> CNDBase();
> - ~CNDBase() {};
> + virtual ~CNDBase();
> +
> +private:
> + // Nobody should use these.
The use of 'private' kind of indicates that.
> + CNDBase( const CNDBase& copyFromMe );
> + CNDBase& operator =(const CNDBase& copyFromMe );
> +
> +public:
> STDMETHODIMP_(ULONG) AddRef();
> STDMETHODIMP_(ULONG) Release();
>
> - virtual void Delete() {};
> + static LONG ObjCount(){ return m_nObj; }
What is this for?
> +};
>
> - volatile LONG m_nRef;
>
> -protected:
> -};
> +extern HANDLE g_hHeap;
> +
> +HRESULT NDConvertWVStatus(HRESULT hr);
> +
> +} // namespace NetworkDirect
> +} // namespace WinVerbs
>
> __inline void* __cdecl operator new(size_t size)
> {
> - return HeapAlloc(GetProcessHeap(), 0, size);
> + return ::HeapAlloc(WinVerbs::NetworkDirect::g_hHeap, 0, size);
> }
>
> -__inline void __cdecl operator delete(void *pObj)
> +__inline void* __cdecl operator new(size_t, void* p)
> {
> - HeapFree(GetProcessHeap(), 0, pObj);
> + return p;
> }
What's the purpose of this call? The user passes in a pointer, and the function returns it.
>
> -HRESULT NDConvertWVStatus(HRESULT hr);
> +__inline void __cdecl operator delete(void *pObj)
> +{
> + ::HeapFree(WinVerbs::NetworkDirect::g_hHeap, 0, pObj);
> +}
>
> #endif // _ND_BASE_H_
> Index: user/nd_base.cpp
> ===================================================================
> --- user/nd_base.cpp (revision 2848)
> +++ user/nd_base.cpp (working copy)
> @@ -1,5 +1,6 @@
> /*
> * Copyright (c) 2009-2010 Intel Corporation. All rights reserved.
> + * Copyright (c) 2010 Microsoft Corporation. All rights reserved.
> *
> * This software is available to you under the OpenIB.org BSD license
> * below:
> @@ -27,18 +28,45 @@
> * SOFTWARE.
> */
>
> +#include "precomp.h"
> #include "nd_base.h"
> -#include <ndstatus.h>
>
> -CNDBase::CNDBase()
> +
> +namespace WinVerbs {
> +namespace NetworkDirect {
> +
> +volatile LONG CNDBase::m_nObj = 0;
> +
> +CNDBase::CNDBase() :
> + m_nRef( 1 )
> {
> - m_nRef = 1;
> + ::InterlockedIncrement( &m_nObj );
The object is being created here. Just assign the value 1 - no need for an interlocked operation.
> +}
> +
> +CNDBase::CNDBase(const CNDBase&) :
> + m_nRef( 1 )
> +{
> + // New object, so we increment m_nObj, but the ref count is 1.
> + ::InterlockedIncrement( &m_nObj );
> +}
> +
> +CNDBase& CNDBase::operator =(const CNDBase&)
> +{
> + // Both objects already exist, don't touch m_nObj.
> + // Don't copy the ref count, either, as that could result
> + // in improper behavior.
> + return *this;
> +}
> +
> +CNDBase::~CNDBase()
> +{
> + ::InterlockedDecrement( &m_nObj );
We're in the destructor here. The reference count should be 0 before the destructor is called, not go to 0 in it.
> }
>
> STDMETHODIMP_(ULONG) CNDBase::
> AddRef(void)
> {
> - return InterlockedIncrement(&m_nRef);
> + return ::InterlockedIncrement(&m_nRef);
> }
>
> STDMETHODIMP_(ULONG) CNDBase::
> @@ -46,19 +74,23 @@ Release(void)
> {
> ULONG ref;
>
> - ref = (ULONG) InterlockedDecrement(&m_nRef);
> - if (ref == 0) {
> - Delete();
> + ref = (ULONG)::InterlockedDecrement(&m_nRef);
> + if (ref == 0){
Put a space before the brace
> + delete this;
> }
> return ref;
> }
>
> HRESULT NDConvertWVStatus(HRESULT hr)
> {
> - switch (hr) {
> + switch (hr){
Put a space before the brace
> case WV_IO_PENDING:
> return ND_PENDING;
Is this mapping still needed for ND 2?
> default:
> return hr;
> }
> }
> +
> +
> +} // namespace NetworkDirect
> +} // namespace WinVerbs
More information about the ofw
mailing list