Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 09:13
Оценка: 20 (2)
Привет всем!

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

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

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

// - header ---
class CBlackMutex
{
  int Size;
  long ResCount;
  HANDLE hEvents[2];
public:
  __fastcall CBlackMutex(int sz=5);
  __fastcall ~CBlackMutex();
  bool __fastcall Open();
  bool __fastcall Release();

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

};
// - code ---
__fastcall CBlackMutex::CBlackMutex(int sz)
{
  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);
}

__fastcall CBlackMutex::~CBlackMutex()
{
  if (hEvents[0] != NULL) CloseHandle(hEvents[0]);
  if (hEvents[1] != NULL) CloseHandle(hEvents[1]);
  hEvents[0] = hEvents[1] = NULL;
}

bool __fastcall 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 __fastcall CBlackMutex::Release()
{
  if (InterlockedExchangeAdd(&ResCount, 0) == 0) return false;
  InterlockedExchangeAdd(&ResCount, -1);          // multithreading -- :D
  if (InterlockedExchangeAdd(&ResCount, 0) == 0)
  {
    SetEvent(hEvents[1]);   // нет проверки ошибок...
  }
  return true;
}


Принимается любая критика по поводу кода.
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;
}


Вот, в общем... Сами просили
Re: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 31.07.02 09:37
Оценка:
Здравствуйте BlackBox, Вы писали:

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


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


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


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

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

BB>
BB>// - header ---
BB>class CBlackMutex
BB>{
BB>  int Size;
BB>  long ResCount;
BB>  HANDLE hEvents[2];
BB>public:
BB>  __fastcall CBlackMutex(int sz=5);
BB>  __fastcall ~CBlackMutex();
BB>  bool __fastcall Open();
BB>  bool __fastcall Release();
BB>
BB>  HANDLE GetEmpty(){return hEvents[1];}
BB>  HANDLE GetOpened(){return hEvents[0];}
BB>
BB>};
BB>// - code ---
BB>__fastcall CBlackMutex::CBlackMutex(int sz)
BB>{
BB>  if (sz <= 0) sz = 1;
BB>  Size = sz;
BB>  ResCount = 0;
BB>  hEvents[0] = hEvents[1] = NULL;
BB>  hEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
BB>  hEvents[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
BB>}

BB>__fastcall CBlackMutex::~CBlackMutex()
BB>{
BB>  if (hEvents[0] != NULL) CloseHandle(hEvents[0]);
BB>  if (hEvents[1] != NULL) CloseHandle(hEvents[1]);
BB>  hEvents[0] = hEvents[1] = NULL;
BB>}

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


BB>


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


я не буду оценивать нужность класса и его функционал, а только попридираюсь к коду. ок?
1. нет конструктора по умолчанию — неудобно
2. зачем нужно
hEvents[0] = hEvents[1] = NULL;

в деструкторе
3. хачем для чтения ResCount использовать InterlockedExchangeAdd(&ResCount, 0)
4. вместо
InterlockedExchangeAdd(&ResCount, 1);

можно просто
InterlockedIncrement(&ResCount);

5. вместо
InterlockedExchangeAdd(&ResCount, -1);

можно просто
InterlockedDecrement(&ResCount);

6. никак не пойму внутреннего смысла функций
HANDLE GetEmpty(){return hEvents[1];}
HANDLE GetOpened(){return hEvents[0];}

по моему их надо было назвать так
BOOL IsEmptyEventValid();
BOOL IsOpenEventValid();
Re[2]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 09:38
Оценка:
Здравствуйте Flamer, Вы писали:

F>Здравствуйте BlackBox, Вы писали:

[skip]

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


ok
[skip]
F>CBlackMutex::CBlackMutex(unsigned int sz) // добавил unsigned
F>{
F> // если unsigned, то проверку можно убрать
F>// if (sz <= 0) sz = 1;
Спасибо, как то не думал об этом.
F> Size = sz;
F> ResCount = 0;
F> hEvents[0] = hEvents[1] = NULL;
F> hEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
F> hEvents[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
F>}

F>CBlackMutex::~CBlackMutex()

F>{
F>// Тут я немножко подрезал код... И так все ясно, без != NULL
Дело привычки
F>// if (hEvents[0] != NULL) CloseHandle(hEvents[0]);
F>// if (hEvents[1] != NULL) CloseHandle(hEvents[1]);

F> if ( hEvents[0] ) CloseHandle(hEvents[0]);

F> if ( hEvents[1] ) CloseHandle(hEvents[1]);

F>// это зачем???

F>// hEvents[0] = hEvents[1] = NULL;
Это у меня параноя такая. Зачем делаю сам не знаю. Но делаю...
F>}

[skip]

F>Вот, в общем... Сами просили


А по поводу GetOpened & GetEmpty???

Да и вообще такая штука нужна кому-нибудь?
Re[2]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 09:44
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте BlackBox, Вы писали:


[skip]

А>я не буду оценивать нужность класса и его функционал, а только попридираюсь к коду. ок?

А>1. нет конструктора по умолчанию — неудобно
CBlackMutex(int sz=5); // <--- не оно?

А>2. зачем нужно
А>
А>hEvents[0] = hEvents[1] = NULL;
А>

А>в деструкторе
А>3. хачем для чтения ResCount использовать InterlockedExchangeAdd(&ResCount, 0)
чтобы получить значение не изменяя его.
[skip]
А>6. никак не пойму внутреннего смысла функций
А>
А>HANDLE GetEmpty(){return hEvents[1];}
А>HANDLE GetOpened(){return hEvents[0];}
А>

у меня в программе один поток ждет, когда либо объект освободится либо, когда его кто-нибудь откроет...
Re[2]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 31.07.02 09:53
Оценка:
Здравствуйте Flamer, Вы писали:

F>Здравствуйте BlackBox, Вы писали:


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


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


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


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

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


F>[покоцано]




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


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


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


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


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

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

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

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

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

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

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

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

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

F>


F>Вот, в общем... Сами просили


И я тут поучаствую
CBlackMutex::~CBlackMutex()
{
// Я бы сделал во как
  if ( hEvents[0] != INVALID_HANDLE_VALUE) CloseHandle(hEvents[0]);
  if ( hEvents[1] != INVALID_HANDLE_VALUE ) CloseHandle(hEvents[1]);

  hEvents[0] = hEvents[1] = INVALID_HANDLE_VALUE; 
}
Alex
Re[3]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 31.07.02 09:56
Оценка:
Здравствуйте BlackBox, Вы писали:

BB>Здравствуйте Алекс, Вы писали:


А>>Здравствуйте BlackBox, Вы писали:


BB>[skip]


А>>я не буду оценивать нужность класса и его функционал, а только попридираюсь к коду. ок?

А>>1. нет конструктора по умолчанию — неудобно
BB>
BB>CBlackMutex(int sz=5); // <--- не оно?
BB>

А>>2. зачем нужно
А>>
А>>hEvents[0] = hEvents[1] = NULL;
А>>

А>>в деструкторе
А>>3. хачем для чтения ResCount использовать InterlockedExchangeAdd(&ResCount, 0)
BB>чтобы получить значение не изменяя его.
BB>[skip]
А>>6. никак не пойму внутреннего смысла функций
А>>
А>>HANDLE GetEmpty(){return hEvents[1];}
А>>HANDLE GetOpened(){return hEvents[0];}
А>>

BB>у меня в программе один поток ждет, когда либо объект освободится либо, когда его кто-нибудь откроет...

А зачем было hEvents[...] обьявлять как private, если потом так спокойно
их отдавать?
Alex
Re[4]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 10:01
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

[skip]

AS>А зачем было hEvents[...] обьявлять как private, если потом так спокойно

AS>их отдавать?

Да, конечно, их можно сделать и public, но как лучше всего сделать в многопоточной среде??
Или и так уже все нормально, и осталось только исправить private на public.
Re[3]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 31.07.02 10:20
Оценка: -1
Здравствуйте Alex Smirnov, Вы писали:

AS>Здравствуйте Flamer, Вы писали:


F>>Здравствуйте BlackBox, Вы писали:


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


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


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


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

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


F>>[покоцано]




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


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


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


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


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

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

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

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

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

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

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

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

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

F>>


F>>Вот, в общем... Сами просили


AS>И я тут поучаствую

AS>
AS>CBlackMutex::~CBlackMutex()
AS>{
AS>// Я бы сделал во как
AS>  if ( hEvents[0] != INVALID_HANDLE_VALUE) CloseHandle(hEvents[0]);
AS>  if ( hEvents[1] != INVALID_HANDLE_VALUE ) CloseHandle(hEvents[1]);

AS>  hEvents[0] = hEvents[1] = INVALID_HANDLE_VALUE; 
AS>}
AS>


ну здесь ты не прав, т.к. в случае ошибки CreateEvent() возвращает NULL, а не INVALID_HANDLE_VALUE.

З.Ы.
INVALID_HANDLE_VALUE = -1
NULL = 0
Re[3]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 31.07.02 10:25
Оценка:
Здравствуйте BlackBox, Вы писали:

BB>Здравствуйте Алекс, Вы писали:


А>>Здравствуйте BlackBox, Вы писали:


BB>[skip]


А>>я не буду оценивать нужность класса и его функционал, а только попридираюсь к коду. ок?

А>>1. нет конструктора по умолчанию — неудобно
BB>
BB>CBlackMutex(int sz=5); // <--- не оно?
BB>


сори, не заметил

BB>чтобы получить значение не изменяя его.


не понял?
Re[4]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 31.07.02 10:32
Оценка: -1
Здравствуйте Алекс, Вы писали:

А>Здравствуйте Alex Smirnov, Вы писали:


AS>>Здравствуйте Flamer, Вы писали:


F>>>Здравствуйте BlackBox, Вы писали:


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


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


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


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

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


F>>>[покоцано]




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


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


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


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


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

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

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

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

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

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

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

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

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

F>>>


F>>>Вот, в общем... Сами просили


AS>>И я тут поучаствую

AS>>
AS>>CBlackMutex::~CBlackMutex()
AS>>{
AS>>// Я бы сделал во как
AS>>  if ( hEvents[0] != INVALID_HANDLE_VALUE) CloseHandle(hEvents[0]);
AS>>  if ( hEvents[1] != INVALID_HANDLE_VALUE ) CloseHandle(hEvents[1]);

AS>>  hEvents[0] = hEvents[1] = INVALID_HANDLE_VALUE; 
AS>>}
AS>>


А>ну здесь ты не прав, т.к. в случае ошибки CreateEvent() возвращает NULL, а не INVALID_HANDLE_VALUE.


А>З.Ы.

А>INVALID_HANDLE_VALUE = -1
А>NULL = 0

Сорри...Был не прав...Исправлюсь
Alex
Re[4]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 10:41
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте BlackBox, Вы писали:


BB>>Здравствуйте Алекс, Вы писали:


А>>>Здравствуйте BlackBox, Вы писали:


BB>>[skip]


А>>>я не буду оценивать нужность класса и его функционал, а только попридираюсь к коду. ок?

А>>>1. нет конструктора по умолчанию — неудобно
BB>>
BB>>CBlackMutex(int sz=5); // <--- не оно?
BB>>


А>сори, не заметил


BB>>чтобы получить значение не изменяя его.


А>не понял?

InterlockedExchangeAdd возвращает предыдущее значение. Следовательно InterlockedExchangeAdd(&ResCount, 0) вернет нам значение ResCount, не изменив его. Может оно конечно можно и просто так прочитать, но лучше уж так...
Re[5]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 31.07.02 10:47
Оценка:
Здравствуйте BlackBox, Вы писали:

хъ

А>>не понял?

BB>InterlockedExchangeAdd возвращает предыдущее значение. Следовательно InterlockedExchangeAdd(&ResCount, 0) вернет нам значение ResCount, не изменив его. Может оно конечно можно и просто так прочитать, но лучше уж так...

Дык чем лучше-то?
Re[6]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 31.07.02 10:56
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте BlackBox, Вы писали:


А>хъ


А>>>не понял?

BB>>InterlockedExchangeAdd возвращает предыдущее значение. Следовательно InterlockedExchangeAdd(&ResCount, 0) вернет нам значение ResCount, не изменив его. Может оно конечно можно и просто так прочитать, но лучше уж так...

А>Дык чем лучше-то?


InterlockedExchangeAdd получает монопольный доступ к изменяемой переменной. Пока она не вернет нам значение никто его изменить не сможет.
Пока тебе писал, мысль родилась может весь код работающий с внутреннми переменными в критическую секцию засунуть? Так действительно будет более монопольный доступ.
Re[7]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 31.07.02 11:20
Оценка:
Здравствуйте BlackBox, Вы писали:

BB>Здравствуйте Алекс, Вы писали:


А>>Здравствуйте BlackBox, Вы писали:


А>>хъ


А>>>>не понял?

BB>>>InterlockedExchangeAdd возвращает предыдущее значение. Следовательно InterlockedExchangeAdd(&ResCount, 0) вернет нам значение ResCount, не изменив его. Может оно конечно можно и просто так прочитать, но лучше уж так...

А>>Дык чем лучше-то?


BB>InterlockedExchangeAdd получает монопольный доступ к изменяемой переменной. Пока она не вернет нам значение никто его изменить не сможет.


Ты думаешь, что пока ты читаешь значение переменной в регистр кто-то ее изменит? Однако!
Re[8]: Изобретен класс что-то типа Mutex'a.
От: Alex Smirnov Россия  
Дата: 31.07.02 11:55
Оценка:
Здравствуйте Алекс, Вы писали:

А>Здравствуйте BlackBox, Вы писали:


BB>>Здравствуйте Алекс, Вы писали:


А>>>Здравствуйте BlackBox, Вы писали:


А>>>хъ


А>>>>>не понял?

BB>>>>InterlockedExchangeAdd возвращает предыдущее значение. Следовательно InterlockedExchangeAdd(&ResCount, 0) вернет нам значение ResCount, не изменив его. Может оно конечно можно и просто так прочитать, но лучше уж так...

А>>>Дык чем лучше-то?


BB>>InterlockedExchangeAdd получает монопольный доступ к изменяемой переменной. Пока она не вернет нам значение никто его изменить не сможет.


А>Ты думаешь, что пока ты читаешь значение переменной в регистр кто-то ее изменит? Однако!


а ты её обьяви как volatile...компилятор её в регистры и не будет запихивать.
Alex
Re[9]: Изобретен класс что-то типа Mutex'a.
От: Kubyshev Andrey  
Дата: 31.07.02 14:46
Оценка:
Chto to eto ochen pohozhe na semafor, esli net, chto ne hvataet v semafore ?
Re[5]: Изобретен класс что-то типа Mutex'a.
От: Хитрик Денис Россия RSDN
Дата: 31.07.02 14:55
Оценка:
Товарищи, имейте совесть!
Зачем ради одной фразы цитировать весть предыдущий ответ, который тоже не блещет предответной обработкой?

Получите ноль.
Правила нашего с вами форума.
Как правильно задавать вопросы. © 2001 by Eric S. Raymond; перевод: © 2002 Валерий Кравчук.
Re[10]: Изобретен класс что-то типа Mutex'a.
От: BlackBox Россия ---
Дата: 01.08.02 04:02
Оценка:
Здравствуйте Kubyshev Andrey, Вы писали:


KA>Chto to eto ochen pohozhe na semafor, esli net, chto ne hvataet v semafore ?


Да название я немного неверное придумал. Это действительно больше похоже на семафор.
Различие в том, что мой объект переходит в свободное состояние дважды (когда полностью свободен и когда только что перешел из свободного состояния), тогда как семафор только, когда его кто-нибудь открывает (насколько я понимаю семафор).
Re[6]: Изобретен класс что-то типа Mutex'a.
От: Алекс Россия http://wise-orm.com
Дата: 01.08.02 04:35
Оценка: 10 (1)
Здравствуйте Хитрик Денис, Вы писали:

ХД>Товарищи, имейте совесть!

ХД>Зачем ради одной фразы цитировать весть предыдущий ответ, который тоже не блещет предответной обработкой?

ХД>Получите ноль.


да просто забыл! извиняюсь.

Вообще лучше сделать так (если сервак совсем нагибается):
1. не показывать текст предыдущего сообщения при ответе
2. завести кнопочку, которая вставляет текст предыдущего сообщения

Это приведет к тому что:
1. будут вставлять цитаты только тогда, когда они действительно нужны
2. уменишит общий вес (в байтах) топика
3. все будут довольны

А кидаться нулями это не метод.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.