1. C++ / Говнокод #12936

    +18

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    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, 25 Апреля 2013

    Комментарии (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 секунд лезем к расшаренным данным без захвата мутекса...
      Ответить
    • > http://www.gamedev.ru/code/tip/tread_creation
      > tread_creation
      > tread
      Ответить
      • > По моему мнению, на данный момент, процесс создания потоков и их синхронизация выглядит не очень красиво, но с приходом С++11 появилась возможность придумать красивое решение
        Ага! Нам хотят рассказать о std::mutex и std::thread... Интересно, почитаем...

        > Для этого нам понадобятся несколько классов и макросов.
        ... фублядь, опять какой-то дурно пахнущий велосипед... Да еще и сплошные непортабельные виндоблядства...
        Ответить
        • вспомнилось вот
          Wife says: "I can't believe it works"
          http://blog.think-async.com/2009/07/wife-says-i-cant-believe-it-works.html
          Ответить
          • "Почему кот яйца лижет? Потому что может!"

            Код, конечно, по-своему красив. Но вот поддерживать такой роллтон в одной функции мне было бы страшновато...
            Ответить
            • > Но вот поддерживать такой роллтон в одной функции мне было бы страшновато... ко ко ко
              Ниасилятор 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
                Ниасилятор метода детекции ниосиляторов детектед
                Ответить
                • >>Ниасилятор метода детекции ниосиляторов детектед
                  Детектор ниасиляторов метода детекции ниосиляторов детектед.
                  Ответить
    • goroutine
      Ответить

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