CHandle критика
От: Аноним  
Дата: 17.08.07 17:35
Оценка:
Выкладываю свой класс для критики

CHandle.h
#pragma once
#include "windows.h"
#include "template.h"

class CHandle {
public:
    OPERATORS;
    CHandle():m_handle(NULL){};
    CHandle(HANDLE handle){
        m_handle = handle;
    }
    ~CHandle(){
        Close();
    }
    void Close();
    bool IsValid() const{
        return (( NULL != _m_handle )&&( INVALID_HANDLE_VALUE != _m_handle ));
    };

    bool Attach(HANDLE h);
    HANDLE Detach();

    HANDLE operator =(HANDLE handle){
        Attach(handle);
        return handle;
    }
    bool operator =(const CHandle& handle);

    bool operator!() const{
        return !IsValid();
    };

    operator HANDLE() const{
        return _m_handle;
    };


    static bool Duplicate(
        HANDLE hSourceProcessHandle,
        HANDLE hSourceHandle,
        HANDLE hTargetProcessHandle,
        LPHANDLE lpTargetHandle,
        DWORD dwDesiredAccess,
        BOOL bInheritHandle,
        DWORD dwOptions
        )
    {
        BOOL result = ::DuplicateHandle(hSourceProcessHandle,hSourceHandle,
            hTargetProcessHandle,lpTargetHandle,
            dwDesiredAccess,bInheritHandle,dwOptions
            );
        return ::FromBOOL(result);
    };
    static bool Duplicate(
        HANDLE hSourceProcessHandle,
        HANDLE hSourceHandle,
        HANDLE hTargetProcessHandle,
        LPHANDLE lpTargetHandle,
        BOOL bInheritHandle = false
        )
    {
        return Duplicate(hSourceProcessHandle,hSourceHandle,hTargetProcessHandle,lpTargetHandle,
            DUPLICATE_SAME_ACCESS,bInheritHandle,DUPLICATE_SAME_ACCESS);
    };

    bool Duplicate(HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,
        DWORD dwDesiredAccess,bool bInheritHandle,DWORD dwOptions) const;
    bool Duplicate(HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,bool bInheritHandle = false) const;
    bool DuplicateFrom(HANDLE hSrcProcess,HANDLE hSrcHandle,
        DWORD dwDesiredAccess = DUPLICATE_SAME_ACCESS,
        bool bInheritHandle = false,
        DWORD dwOptions = DUPLICATE_SAME_ACCESS);

    DWORD Wait(DWORD timeout) const{
        return WaitForSingleObject(_m_handle,timeout);
    }

    DWORD WaitInfinite() const;

    static DWORD WaitForMultipleObjects(IN DWORD nCount,IN CONST CHandle* lpHandles,
        IN BOOL bWaitAll, IN DWORD dwMilliseconds)
    {
        return ::WaitForMultipleObjects(nCount,(HANDLE*)lpHandles,bWaitAll,dwMilliseconds);
    }

    HANDLE Handle(){
        return _m_handle;
    }

    //__declspec(property(get=get_Handle,put=put_Handle)) HANDLE __Handle;
    //HANDLE get_Handle(){
    //    return m_handle;
    //};
    //void put_Handle(HANDLE handle){
    //    Attach(handle);
    //};
private:
    __declspec(property(get=get_m_handle,put=put_m_handle)) HANDLE _m_handle;
    HANDLE get_m_handle() const {
        return m_handle;
    };
    void put_m_handle(HANDLE handle){
#if F_LIB_TEST
        if ( m_handle != handle ){
            dpf(("handle changed: %lx -> %lx",m_handle,handle));
        }
#endif
        m_handle = handle;
    };


    HANDLE m_handle;
};




#include "stdafx.h"
#include "CHandle.h"

void CHandle::Close()
{
    __mytry;
    if ( IsValid() ){
        CloseHandle(_m_handle);
        _m_handle = NULL;
    }
    __myexcept_void;
}

bool CHandle::Attach(HANDLE h)
{
    Close();
    _m_handle = h;
    return IsValid();
}

HANDLE CHandle::Detach(){
    HANDLE h = _m_handle;
    _m_handle = NULL;
    return h;
}

bool CHandle::operator =(const CHandle& handle)
{
    Close();
    handle.Duplicate(GetCurrentProcess(),&m_handle);
    return IsValid();
}

DWORD CHandle::WaitInfinite() const
{
    __mytry;
    return Wait(INFINITE);
    __myexcept(WAIT_FAILED);
}

bool CHandle::Duplicate(HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,
                     DWORD dwDesiredAccess,bool bInheritHandle,DWORD dwOptions) const
{
    __mytry;
    BOOL result = Duplicate(GetCurrentProcess(),_m_handle,hTargetProcessHandle,lpTargetHandle,
        dwDesiredAccess,bInheritHandle,dwOptions);
    return FromBOOL(result);
    __myexcept(false);
}

bool CHandle::Duplicate(HANDLE hTargetProcessHandle,LPHANDLE lpTargetHandle,bool bInheritHandle) const
{
    __mytry;
    return Duplicate(hTargetProcessHandle,lpTargetHandle,
        DUPLICATE_SAME_ACCESS,bInheritHandle,DUPLICATE_SAME_ACCESS);
    __myexcept(false);
}

bool CHandle::DuplicateFrom(HANDLE hSrcProcess,HANDLE hSrcHandle,
                   DWORD dwDesiredAccess,bool bInheritHandle,DWORD dwOptions)
{
    __mytry;
    Close();
    return Duplicate(hSrcProcess,hSrcHandle,GetCurrentProcess(),&m_handle,dwDesiredAccess,bInheritHandle,dwOptions);
    __myexcept(false);
};



Какая политика с вашей точки зрения более правильная?

1.
HANDLE hProcess;
CHandle handle = hProcess;
handle = hThread; //генерируется исключение, что бы избегать таких ситуаций. Как бы одна перемення — один ресурс и хранить в ней разные — не красиво как-то

2.
HANDLE hThread;
CHandle h = hProcess;
h = hThread; //h.Close(); h.handle = hThread закрывается текущий хендл и присваевается новое значение

====================================================
CHandle h1,h2;
h1 = h2;

что должно выполняться в этом случае DuplicateHandle или (h1.Close();h1.handle = h2.handle;h2.handle = NULL)????
Re: CHandle критика
От: remark Россия http://www.1024cores.net/
Дата: 17.08.07 23:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Выкладываю свой класс для критики


Ой-ой-ой. Какой же он плохой.



1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: CHandle критика
От: Sni4ok  
Дата: 18.08.07 07:10
Оценка:
ты самто это юзаешь?
Re: CHandle критика
От: Awaken Украина  
Дата: 18.08.07 07:29
Оценка:
А>Выкладываю свой класс для критики

имхо в таком виде — малополезный велосипед.
сделал бы тогда уж на шаблонных стратегиях, ибо разные виды ресурсов должны закрываться,
и проверяться на валидность, по разному.
что если тебе VirtualAlloc понадобиться?
Re: CHandle критика
От: igna Россия  
Дата: 18.08.07 07:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Выкладываю свой класс для критики


Можно пример использования?
Re[2]: CHandle критика
От: Аноним  
Дата: 18.08.07 11:03
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>Выкладываю свой класс для критики


R>Ой-ой-ой. Какой же он плохой.

R>

R>


хочу услышать аргументы. что,почему?
Re[2]: CHandle критика
От: Аноним  
Дата: 18.08.07 11:09
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Аноним, Вы писали:


А>>Выкладываю свой класс для критики


I>Можно пример использования?


CHandle реализует базовый функции работы с хендлом и наследуется классами CEvent, CMutex, CThread....
Re: CHandle критика
От: Кодт Россия  
Дата: 20.08.07 08:46
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Выкладываю свой класс для критики


1) Очень тяжеловесный.

2) Для копирования используются функции ядра — это дорогостояще, во-первых, и не даёт возможности сравнивать хэндлы, во-вторых.
HANDLE h0 = .....;
CHandle h1 = h0;
assert(h0 == h1); // failed!!!


3) Жёстко привязан к одному типу хэндлов — на объекты ядра. Переделать на другие типы — фактически, переписать заново.

А>Какая политика с вашей точки зрения более правильная?


Воот!
Из-за тяжеловесности и монолитности класса ты не можешь по-быстрому сделать разные политики владения
— монопольное (аналогично scoped_ptr)
— распределённое (аналогично shared_ptr)
— эстафетное (аналогично auto_ptr)

И кстати, политики обработки ошибок (повторное присваивание, например) тоже могут варьироваться.
— assert(false)
— throw

К тому же, повторное присваивание иногда может быть штатным.
SOME theBest = SomeDefault();
for(.....)
{
    SOME pretendor = GetNext();
    if(IsBetter(pretendor, theBest))
        theBest = pretendor;
}
.....

В таких случаях можно сделать функцию явного присваивания — не operator=, а, скажем, reset.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: CHandle критика
От: Awaken Украина  
Дата: 20.08.07 09:23
Оценка:
К>Из-за тяжеловесности и монолитности класса ты не можешь по-быстрому сделать разные политики владения
К>- монопольное (аналогично scoped_ptr)
К>- распределённое (аналогично shared_ptr)
К>- эстафетное (аналогично auto_ptr)

К>И кстати, политики обработки ошибок (повторное присваивание, например) тоже могут варьироваться.

К>- assert(false)
К>- throw

вот поэтому его нужно делать шаблонным и разложить на классы-стратегии .
например такие:
-ownership
-checking (throw/nothrow/разные виды сравнения)
-closing (чем закрывать ресурс)

в результате должно получиться что-то типа:
SuperSmartHandle<Scoped, Throw, ReleaseSem> semaphore_handle;
SuperSmartHandle<Scoped, NoThrow, Close> file_handle;
и т.д.
Re[3]: CHandle критика
От: Кодт Россия  
Дата: 20.08.07 10:47
Оценка:
Здравствуйте, Awaken, Вы писали:

A>вот поэтому его нужно делать шаблонным и разложить на классы-стратегии .

A>например такие:
A>-ownership
A>-checking (throw/nothrow/разные виды сравнения)
A>-closing (чем закрывать ресурс)
Сюда же — а какой, собственно, голый тип: HANDLE, int, HBLABLABLA...

A>в результате должно получиться что-то типа:


Возможно, что удобнее не валить в кучу все параметры (которых получается много), а сделать генератор типов на миксинах.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: CHandle критика
От: Аноним  
Дата: 21.08.07 10:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Выкладываю свой класс для критики


А>CHandle.h

А>[ccode]
А>#pragma once
А>#include "windows.h"
А>#include "template.h"

А>class CHandle {

Вообще-то, уже есть класс CHandle, смотрите файл atlbase.h
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.