)]}'
{
  "commit": "d3038a56151180995f1f74c008f4193337bbdec3",
  "tree": "fc332fcca43a880a9acfe7cb5c0eed9034cbd213",
  "parents": [
    "e6ccafef01f597be624f54147e3daab1f67804d9"
  ],
  "author": {
    "name": "Dmitry Volyntsev",
    "email": "xeioex@nginx.com",
    "time": "Mon Nov 21 16:03:42 2016 +0300"
  },
  "committer": {
    "name": "Dmitry Volyntsev",
    "email": "xeioex@nginx.com",
    "time": "Mon Nov 21 16:03:42 2016 +0300"
  },
  "message": "Events: improved error event handling for UDP sockets.\n\nNormally, the epoll module calls the read and write handlers depending\non whether EPOLLIN and EPOLLOUT are reported by epoll_wait().  No error\nprocessing is done in the module, the handlers are expected to get an\nerror when doing I/O.\n\nIf an error event is reported without EPOLLIN and EPOLLOUT, the module\nset both EPOLLIN and EPOLLOUT to ensure the error event is handled at\nleast in one active handler.\n\nThis works well unless the error is delivered along with only one of\nEPOLLIN or EPOLLOUT, and the corresponding handler does not do any I/O.\nFor example, it happened when getting EPOLLERR|EPOLLOUT from\nepoll_wait() upon receiving \"ICMP port unreachable\" while proxying UDP.\nAs the write handler had nothing to send it was not able to detect and\nlog an error, and did not switch to the next upstream.\n\nThe fix is to unconditionally set EPOLLIN and EPOLLOUT in case of an\nerror event.  In the aforementioned case, this causes the read handler\nto be called which does recv() and detects an error.\n\nIn addition to the epoll module, analogous changes were made in\ndevpoll/eventport/poll.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "f985fbdfb474cde05a9bb0420cf2fc1afc458828",
      "old_mode": 33188,
      "old_path": "src/event/modules/ngx_devpoll_module.c",
      "new_id": "39e480ec8fbf08baee7ce10116d481bb63097e5d",
      "new_mode": 33188,
      "new_path": "src/event/modules/ngx_devpoll_module.c"
    },
    {
      "type": "modify",
      "old_id": "c267fd6c7a83fd660ff3df0228ca77d8d5d2b191",
      "old_mode": 33188,
      "old_path": "src/event/modules/ngx_epoll_module.c",
      "new_id": "760c69b9a0c9e751c686271c1bc3b3de1e0429c2",
      "new_mode": 33188,
      "new_path": "src/event/modules/ngx_epoll_module.c"
    },
    {
      "type": "modify",
      "old_id": "dafa27f6a3a97866974672de07b193191362afd3",
      "old_mode": 33188,
      "old_path": "src/event/modules/ngx_eventport_module.c",
      "new_id": "041359948c63ca1a184e2022333c945647794fab",
      "new_mode": 33188,
      "new_path": "src/event/modules/ngx_eventport_module.c"
    },
    {
      "type": "modify",
      "old_id": "4370950c09ecdea5242cc2181809464bd854c960",
      "old_mode": 33188,
      "old_path": "src/event/modules/ngx_poll_module.c",
      "new_id": "a2a7079d62794b3a61c95a8699ab6a5e1b4e55a3",
      "new_mode": 33188,
      "new_path": "src/event/modules/ngx_poll_module.c"
    }
  ]
}
