Здравствуйте, Aleksey_NN, Вы писали:
A_N>Здравствуйте, shrecher, Вы писали:
S>>Простой вопрос: поддержка целостности объекта через счетчик ссылок как в COM-t. Написать методы AddRef, Release.
A_N>Обычно приводят что-то такое:
A_N>A_N>void CReferenceCounter::AddRef( void ) {
A_N> ::IntrlockedIncrement( &m_nReferences );
A_N>}
A_N>void CReferenceCounter::Release( void ) {
A_N> if( !::IntrlockedDecrement( &m_nReferences ) ) {
A_N> delete this;
A_N> }
A_N>}
A_N>
A_N>Либо синхронизируют через критическую секцию. А мне вот интересно, тут безопасно разве удалять объект? Если бы синхронизировали критической секцией, она бы была мембером класса, как удалить объект? Выйти из нее — а может в это время другой поток addRef сделает, а потом текущий, думая что счетчик 0, уничтожит. Не выходить из нее тоже нельзя.
A_N>Да и тут примерно такая ситуация вроде может быть — зашли в аddRef, в это время другой поток декрементировал и стер объект, и тут мы дошли в первом поток до вызова IntrlockedIncrement(). Может так быть?
Здесь все просто, всего лишь нужно задуматься "а кто может делать AddRef" ?
Ответ : тот кто имеет "валидный" интерфейс/хэндл, то есть пока этот хэндл валидный,
объект не будет удален даже вызовом Release() из другого потока.
Т.е. объект будет удален при вызове Release() у последнего "валидного" хэндла.
Все это значит, чтобы передать "валидный" хэндл в другой поток, нужно сначала сделать ему AddRef()
и только потом передавать в др поток (тогда можно считать, что в новом потоке "валидный" хэндл).