Кресты / Говнокод #12936 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
class Mutex
{
  HANDLE m_Mutex;
public:
  Mutex()
  {
    m_Mutex = CreateMutex(0, false, 0);
  }

  ~Mutex()
  {
    ReleaseMutex(m_Mutex);
    CloseHandle(m_Mutex);
  }

  void Lock()
  {
    auto lv_WaitResult = WaitForSingleObject(m_Mutex, 10000);
    assert(lv_WaitResult != WAIT_TIMEOUT);
  }

  void Unlock()
  {
    ReleaseMutex(m_Mutex);
  }
};


template<int C>
struct GLocker
{
  static Mutex m_Mutex;
};
template<int C>  Mutex GLocker<C>::m_Mutex;

class Locker
{
  Mutex *m_Mutex;

public:
  Locker(Mutex &_Mutex)
  {
    m_Mutex = &_Mutex;
    m_Mutex->Lock();
  }

  virtual ~Locker()
  {
    m_Mutex->Unlock();
  }
};


class ThreadCreator
{
protected:
  static void NewThread(void *_Func)
  {
    (*(std::function<void()>*)_Func)();
    delete (std::function<void()>*)_Func;
  }

public:
  static ThreadCreator g_ThreadCreator;

  HANDLE operator=(const std::function<void()> &_Func)
  {
    std::function<void()> *lv_Func = new std::function<void()>(_Func);
    return (HANDLE)_beginthread(ThreadCreator::NewThread,0,(void*)lv_Func);
  }
};
ThreadCreator ThreadCreator::g_ThreadCreator;


#define LOCK const Locker  _Lock##__LINE__##__COUNTER__ = GLocker<9000 + __COUNTER__>::m_Mutex // 9000 является запасом для пользовательских номеров.
#define LOCK_EX(Port) const Locker  _Lock##__LINE__##__COUNTER__ = GLocker<Port>::m_Mutex // блокирует определённый мьютекс, полезно когда нужно делать синхронизацию из разных мест.

#define GO_FUNC ThreadCreator::g_ThreadCreator = 
#define GO_EX(...) GO_FUNC  [__VA_ARGS__]() mutable -> void
#define GO GO_FUNC  []() -> void

Подсказка сайта:
http://www.gamedev.ru/code/tip/tread_creation

Запостил: LispGovno LispGovno, (Updated )

Комментарии (26) RSS

  • ура, ГК заработал

    опять позоришь непонятого гения? что о тебе скажут потомки? дантес померкнет перед твоим презренным именем
    Ответить
  • Если в первый раз поюзать два ЛОКа на одной строке в разных единицах компиляции, то...
    Ответить
  • Бустоненавистничество и крестобесие. Какое лечение назначите, господа?
    Ответить
  • В крестах тащить чужеродные фишечки из других языков занятие, как правило, архинеблагодарное, а порой и просто глупое. Особенно, если не сохраняешь семантики.
    У крестов свой, особенный путь - каждый раз писать велики.
    Ответить
  • Зачем в Locker виртуальный деструктор?
    И как beginthread из указателя на стд::факшен работает?
    std::function<void()> *lv_Func = new std::function<void()>(_Func);
        return (HANDLE)_beginthread(ThreadCreator::NewThread,0,(void*)lv_Func);
    Ответить
    • C beginthread все верно. Но первый вопрос остался. Видимо в Locker виртуальный деструктор, чтобы процессор сильно не разгонялся
      Ответить
      • Да не, просто память засрать. Если я не туплю - компилятор вставит здесь прямой вызов деструктора вместо виртуального как и в любом другом случае разрушения не через ссылку/указатель.
        Ответить
        • Ты же мне вроде доказывал когда-то (и у тебя получилось), что если объект расположен по ссылке, то в каких-то случаях компилятор по стандарту обязан вставить прямой вызов деструктора. Вплоть до того, что можно сделать деструктор невиртуальным, а вызовется все равно правильный деструктор потомка. (Тоже самое ты доказал и про shared_ptr)
          Ответить
          • Эээ. А можно ссылку на доказательство?

            Виртуальный вызов по ссылке он может оптимизнуть только в том случае, если уверен в типе объекта (например если сам объект описан в теле той же функции).

            А деструктор-то можно сделать невиртуальным. И если удалять через ссылку/указатель на правильный тип - все будет ок. Если через указатель на предка - будет фейл.
            Ответить
            • Твоё уже не найду, но:
              http://ideone.com/jBSFyJ
              Виртуального деструктора нет, а правильный деструктор вызывается. Ну а про shared_ptr ты и сам знаешь почему виртуальный деструктор не нужен
              Ответить
              • > http://ideone.com/jBSFyJ
                Так это деструктор от временного объекта D() сработал. Куда он денется то? Это как я и написал выше "например если сам объект описан в теле той же функции".

                > про shared_ptr ты и сам знаешь почему виртуальный деструктор не нужен
                Ну кроме не совсем корретных случаев, когда успели кастануть к предку перед тем, как засунуть в шаропоинтер.
                Ответить
  • auto lv_WaitResult = WaitForSingleObject(m_Mutex, 10000);
    assert(lv_WaitResult != WAIT_TIMEOUT);
    Отличный deadlock-resolution... Просто офигенный... При отключенных ассертах через 10 секунд лезем к расшаренным данным без захвата мутекса...
    Ответить
    • > По моему мнению, на данный момент, процесс создания потоков и их синхронизация выглядит не очень красиво, но с приходом С++11 появилась возможность придумать красивое решение
      Ага! Нам хотят рассказать о std::mutex и std::thread... Интересно, почитаем...

      > Для этого нам понадобятся несколько классов и макросов.
      ... фублядь, опять какой-то дурно пахнущий велосипед... Да еще и сплошные непортабельные виндоблядства...
      Ответить
        • "Почему кот яйца лижет? Потому что может!"

          Код, конечно, по-своему красив. Но вот поддерживать такой роллтон в одной функции мне было бы страшновато...
          Ответить
          • > Но вот поддерживать такой роллтон в одной функции мне было бы страшновато... ко ко ко
            Ниасилятор boost::asio, коорутин и boost::lambda detected. Пrаативный.

            Интересно, какой ферймворк коорутин использовали? Потому что switch-caseный не умеет в исключения и в объекты с деструкторами.
            Ответить
            • > Ниасилятор boost::asio
              Вполне так осилятор. Таймер разве что неудобный, а так либа годная (юзаю ее удп сервер и таймеры).

              > boost::lambda
              Ну не люблю я лямбды в императивном коде. Умеренно юзаю, в тех местах где они удобны и не превышают пары строчек, но код на одних лямбдах аля
              нода-жс считаю ролтоном.

              > Потому что switch-caseный не умеет в исключения и в объекты с деструкторами.
              Может быть первые прототипы boost::coroutine с переключалкой стеков?
              Ответить
            • P.S. Насчет ниасиляторства - ну вот spirit + phoenix недавно поюзал в проекте ради небольшого парсера булевых выражений (сравнения, логика, интовые и буловы свойства объекта аля "open && weight > 10"). Само описание грамматики понравилось, много времени на его составление не ушло, а вот феникс - не приглянулся. И юзать его вне связки со спиритом желания никакого нет.

              Не всё, что осилено должно понравиться, ой не всё...

              P.S. Если интересно - могу выложить сей говнопарсер на всеобщее порицание 😉
              Ответить
            • > Ниасилятор boost::asio, коорутин и boost::lambda detected
              Ниасилятор метода детекции ниосиляторов детектед
              Ответить
              • >>Ниасилятор метода детекции ниосиляторов детектед
                Детектор ниасиляторов метода детекции ниосиляторов детектед.
                Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8