Re: Изобретен класс что-то типа Mutex'a.
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 31.07.02 09:29
Оценка: 9 (2)
Здравствуйте BlackBox, Вы писали:

BB>Привет всем!


BB> Вот написал маленький класс и думаю не изобрел ли я велосипед (в который раз... )


BB> Как его обозвать даже не знаю, и как описать тоже, но попробую.


BB>Итак, имеется у нас объект. Его можно Open и Release (по аналогии с mutex'oм). Открыть его можно только N раз, как только все его освободили то у нас устанавливается событие. Как только его кто-то открыл тоже устанавливается событие, но другое. Пока писал эти строки, пришло в голову, что N раз это не принципиально. Вот вообщем-то и все.

BB>Можно пользовать в многопоточном приложении (для этого и задумывался), но есть сумнения. может вы, уважаемый алл, подскажите (выделенно жирным).


[покоцано]



BB>Принимается любая критика по поводу кода.


Любую критику, говорите, принимаете? Итак:

1. Уберите от греха __fastcall. Тогда класс можно будет использовать в средах, отличных от Borland C++ Builder .

2. По коду (убрал все __fastcall, ну и так, замечания по ходу):

// - header ---
class CBlackMutex
{
  int Size;
  long ResCount;
  HANDLE hEvents[2];
public:
  CBlackMutex(int sz=5); // лучше unsigned int
   ~CBlackMutex();
  bool Open();
  bool Release();

  HANDLE GetEmpty(){return hEvents[1];}
  HANDLE GetOpened(){return hEvents[0];}

};
// - code ---
CBlackMutex::CBlackMutex(unsigned int sz) // добавил unsigned 
{
  // если unsigned, то проверку можно убрать
//  if (sz <= 0) sz = 1;   

  Size = sz;
  ResCount = 0;
  hEvents[0] = hEvents[1] = NULL;
  hEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
  hEvents[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
}

CBlackMutex::~CBlackMutex()
{
// Тут я немножко подрезал код... И так все ясно, без != NULL

//  if (hEvents[0] != NULL) CloseHandle(hEvents[0]);
//  if (hEvents[1] != NULL) CloseHandle(hEvents[1]);

  if ( hEvents[0] ) CloseHandle(hEvents[0]);
  if ( hEvents[1] ) CloseHandle(hEvents[1]);

// это зачем??? 
//  hEvents[0] = hEvents[1] = NULL; 
}

bool CBlackMutex::Open()
{
  if (InterlockedExchangeAdd(&ResCount, 0) == Size) return false;
  if (InterlockedExchangeAdd(&ResCount, 0) == 0)
  {
    SetEvent(hEvents[0]);   // нет проверки ошибок...
  }
  InterlockedExchangeAdd(&ResCount, 1);           // multithreading ++ :D
  return true;
}
bool CBlackMutex::Release()
{
  if (InterlockedExchangeAdd(&ResCount, 0) == 0) return false;
  InterlockedExchangeAdd(&ResCount, -1);          // multithreading -- :D
  if (InterlockedExchangeAdd(&ResCount, 0) == 0)
  {
    SetEvent(hEvents[1]);   // нет проверки ошибок...
  }
  return true;
}


Вот, в общем... Сами просили
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.