We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug: Deadlock 'fix' introduced deadlock.
Since https://github.com/open-mmlab/mmcv/pull/252 is merged my mmdetection code hangs after evaluation. After reverting the specific commit `git revert c203419f57c2e25ab4307420b9a3688f99e01dea`, my code runs again as expected..

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmcv/runner/hooks/logger/text.py`
Content:
```
1 # Copyright (c) Open-MMLab. All rights reserved.
2 import datetime
3 import os.path as osp
4 from collections import OrderedDict
5 
6 import torch
7 import torch.distributed as dist
8 
9 import mmcv
10 from ..hook import HOOKS
11 from .base import LoggerHook
12 
13 
14 @HOOKS.register_module
15 class TextLoggerHook(LoggerHook):
16 
17     def __init__(self, interval=10, ignore_last=True, reset_flag=False):
18         super(TextLoggerHook, self).__init__(interval, ignore_last, reset_flag)
19         self.time_sec_tot = 0
20 
21     def before_run(self, runner):
22         super(TextLoggerHook, self).before_run(runner)
23         self.start_iter = runner.iter
24         self.json_log_path = osp.join(runner.work_dir,
25                                       f'{runner.timestamp}.log.json')
26         if runner.meta is not None:
27             self._dump_log(runner.meta, runner)
28 
29     def _get_max_memory(self, runner):
30         mem = torch.cuda.max_memory_allocated()
31         mem_mb = torch.tensor([mem / (1024 * 1024)],
32                               dtype=torch.int,
33                               device=torch.device('cuda'))
34         if runner.world_size > 1:
35             dist.reduce(mem_mb, 0, op=dist.ReduceOp.MAX)
36         return mem_mb.item()
37 
38     def _log_info(self, log_dict, runner):
39         if runner.mode == 'train':
40             log_str = f'Epoch [{log_dict["epoch"]}]' \
41                       f'[{log_dict["iter"]}/{len(runner.data_loader)}]\t' \
42                       f'lr: {log_dict["lr"]:.5f}, '
43             if 'time' in log_dict.keys():
44                 self.time_sec_tot += (log_dict['time'] * self.interval)
45                 time_sec_avg = self.time_sec_tot / (
46                     runner.iter - self.start_iter + 1)
47                 eta_sec = time_sec_avg * (runner.max_iters - runner.iter - 1)
48                 eta_str = str(datetime.timedelta(seconds=int(eta_sec)))
49                 log_str += f'eta: {eta_str}, '
50                 log_str += f'time: {log_dict["time"]:.3f}, ' \
51                            f'data_time: {log_dict["data_time"]:.3f}, '
52                 # statistic memory
53                 if torch.cuda.is_available():
54                     log_str += f'memory: {log_dict["memory"]}, '
55         else:
56             log_str = 'Epoch({log_dict["mode"]}) ' \
57                       f'[{log_dict["epoch"] - 1}][{log_dict["iter"]}]\t'
58         log_items = []
59         for name, val in log_dict.items():
60             # TODO: resolve this hack
61             # these items have been in log_str
62             if name in [
63                     'mode', 'Epoch', 'iter', 'lr', 'time', 'data_time',
64                     'memory', 'epoch'
65             ]:
66                 continue
67             if isinstance(val, float):
68                 val = f'{val:.4f}'
69             log_items.append(f'{name}: {val}')
70         log_str += ', '.join(log_items)
71         runner.logger.info(log_str)
72 
73     def _dump_log(self, log_dict, runner):
74         # dump log in json format
75         json_log = OrderedDict()
76         for k, v in log_dict.items():
77             json_log[k] = self._round_float(v)
78         # only append log at last line
79         if runner.rank == 0:
80             with open(self.json_log_path, 'a+') as f:
81                 mmcv.dump(json_log, f, file_format='json')
82                 f.write('\n')
83 
84     def _round_float(self, items):
85         if isinstance(items, list):
86             return [self._round_float(item) for item in items]
87         elif isinstance(items, float):
88             return round(items, 5)
89         else:
90             return items
91 
92     def log(self, runner):
93         log_dict = OrderedDict()
94         # training mode if the output contains the key "time"
95         mode = 'train' if 'time' in runner.log_buffer.output else 'val'
96         log_dict['mode'] = mode
97         log_dict['epoch'] = runner.epoch + 1
98         log_dict['iter'] = runner.inner_iter + 1
99         # only record lr of the first param group
100         log_dict['lr'] = runner.current_lr()[0]
101         memory = None
102         if torch.cuda.is_available():
103             memory = self._get_max_memory(runner)
104         if mode == 'train':
105             log_dict['time'] = runner.log_buffer.output['time']
106             log_dict['data_time'] = runner.log_buffer.output['data_time']
107 
108             # statistic memory
109             if memory is not None:
110                 log_dict['memory'] = memory
111         for name, val in runner.log_buffer.output.items():
112             if name in ['time', 'data_time']:
113                 continue
114             log_dict[name] = val
115 
116         self._log_info(log_dict, runner)
117         self._dump_log(log_dict, runner)
118
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mmcv/runner/hooks/logger/text.py b/mmcv/runner/hooks/logger/text.py
--- a/mmcv/runner/hooks/logger/text.py
+++ b/mmcv/runner/hooks/logger/text.py
@@ -98,16 +98,13 @@
         log_dict['iter'] = runner.inner_iter + 1
         # only record lr of the first param group
         log_dict['lr'] = runner.current_lr()[0]
-        memory = None
-        if torch.cuda.is_available():
-            memory = self._get_max_memory(runner)
         if mode == 'train':
             log_dict['time'] = runner.log_buffer.output['time']
             log_dict['data_time'] = runner.log_buffer.output['data_time']
 
             # statistic memory
-            if memory is not None:
-                log_dict['memory'] = memory
+            if torch.cuda.is_available():
+                log_dict['memory'] = self._get_max_memory(runner)
         for name, val in runner.log_buffer.output.items():
             if name in ['time', 'data_time']:
                 continue

{"golden_diff": "diff --git a/mmcv/runner/hooks/logger/text.py b/mmcv/runner/hooks/logger/text.py\n--- a/mmcv/runner/hooks/logger/text.py\n+++ b/mmcv/runner/hooks/logger/text.py\n@@ -98,16 +98,13 @@\n         log_dict['iter'] = runner.inner_iter + 1\n         # only record lr of the first param group\n         log_dict['lr'] = runner.current_lr()[0]\n-        memory = None\n-        if torch.cuda.is_available():\n-            memory = self._get_max_memory(runner)\n         if mode == 'train':\n             log_dict['time'] = runner.log_buffer.output['time']\n             log_dict['data_time'] = runner.log_buffer.output['data_time']\n \n             # statistic memory\n-            if memory is not None:\n-                log_dict['memory'] = memory\n+            if torch.cuda.is_available():\n+                log_dict['memory'] = self._get_max_memory(runner)\n         for name, val in runner.log_buffer.output.items():\n             if name in ['time', 'data_time']:\n                 continue\n", "issue": "Bug: Deadlock 'fix' introduced deadlock.\nSince https://github.com/open-mmlab/mmcv/pull/252 is merged my mmdetection code hangs after evaluation. After reverting the specific commit `git revert c203419f57c2e25ab4307420b9a3688f99e01dea`, my code runs again as expected..\n", "before_files": [{"content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport datetime\nimport os.path as osp\nfrom collections import OrderedDict\n\nimport torch\nimport torch.distributed as dist\n\nimport mmcv\nfrom ..hook import HOOKS\nfrom .base import LoggerHook\n\n\n@HOOKS.register_module\nclass TextLoggerHook(LoggerHook):\n\n    def __init__(self, interval=10, ignore_last=True, reset_flag=False):\n        super(TextLoggerHook, self).__init__(interval, ignore_last, reset_flag)\n        self.time_sec_tot = 0\n\n    def before_run(self, runner):\n        super(TextLoggerHook, self).before_run(runner)\n        self.start_iter = runner.iter\n        self.json_log_path = osp.join(runner.work_dir,\n                                      f'{runner.timestamp}.log.json')\n        if runner.meta is not None:\n            self._dump_log(runner.meta, runner)\n\n    def _get_max_memory(self, runner):\n        mem = torch.cuda.max_memory_allocated()\n        mem_mb = torch.tensor([mem / (1024 * 1024)],\n                              dtype=torch.int,\n                              device=torch.device('cuda'))\n        if runner.world_size > 1:\n            dist.reduce(mem_mb, 0, op=dist.ReduceOp.MAX)\n        return mem_mb.item()\n\n    def _log_info(self, log_dict, runner):\n        if runner.mode == 'train':\n            log_str = f'Epoch [{log_dict[\"epoch\"]}]' \\\n                      f'[{log_dict[\"iter\"]}/{len(runner.data_loader)}]\\t' \\\n                      f'lr: {log_dict[\"lr\"]:.5f}, '\n            if 'time' in log_dict.keys():\n                self.time_sec_tot += (log_dict['time'] * self.interval)\n                time_sec_avg = self.time_sec_tot / (\n                    runner.iter - self.start_iter + 1)\n                eta_sec = time_sec_avg * (runner.max_iters - runner.iter - 1)\n                eta_str = str(datetime.timedelta(seconds=int(eta_sec)))\n                log_str += f'eta: {eta_str}, '\n                log_str += f'time: {log_dict[\"time\"]:.3f}, ' \\\n                           f'data_time: {log_dict[\"data_time\"]:.3f}, '\n                # statistic memory\n                if torch.cuda.is_available():\n                    log_str += f'memory: {log_dict[\"memory\"]}, '\n        else:\n            log_str = 'Epoch({log_dict[\"mode\"]}) ' \\\n                      f'[{log_dict[\"epoch\"] - 1}][{log_dict[\"iter\"]}]\\t'\n        log_items = []\n        for name, val in log_dict.items():\n            # TODO: resolve this hack\n            # these items have been in log_str\n            if name in [\n                    'mode', 'Epoch', 'iter', 'lr', 'time', 'data_time',\n                    'memory', 'epoch'\n            ]:\n                continue\n            if isinstance(val, float):\n                val = f'{val:.4f}'\n            log_items.append(f'{name}: {val}')\n        log_str += ', '.join(log_items)\n        runner.logger.info(log_str)\n\n    def _dump_log(self, log_dict, runner):\n        # dump log in json format\n        json_log = OrderedDict()\n        for k, v in log_dict.items():\n            json_log[k] = self._round_float(v)\n        # only append log at last line\n        if runner.rank == 0:\n            with open(self.json_log_path, 'a+') as f:\n                mmcv.dump(json_log, f, file_format='json')\n                f.write('\\n')\n\n    def _round_float(self, items):\n        if isinstance(items, list):\n            return [self._round_float(item) for item in items]\n        elif isinstance(items, float):\n            return round(items, 5)\n        else:\n            return items\n\n    def log(self, runner):\n        log_dict = OrderedDict()\n        # training mode if the output contains the key \"time\"\n        mode = 'train' if 'time' in runner.log_buffer.output else 'val'\n        log_dict['mode'] = mode\n        log_dict['epoch'] = runner.epoch + 1\n        log_dict['iter'] = runner.inner_iter + 1\n        # only record lr of the first param group\n        log_dict['lr'] = runner.current_lr()[0]\n        memory = None\n        if torch.cuda.is_available():\n            memory = self._get_max_memory(runner)\n        if mode == 'train':\n            log_dict['time'] = runner.log_buffer.output['time']\n            log_dict['data_time'] = runner.log_buffer.output['data_time']\n\n            # statistic memory\n            if memory is not None:\n                log_dict['memory'] = memory\n        for name, val in runner.log_buffer.output.items():\n            if name in ['time', 'data_time']:\n                continue\n            log_dict[name] = val\n\n        self._log_info(log_dict, runner)\n        self._dump_log(log_dict, runner)\n", "path": "mmcv/runner/hooks/logger/text.py"}], "after_files": [{"content": "# Copyright (c) Open-MMLab. All rights reserved.\nimport datetime\nimport os.path as osp\nfrom collections import OrderedDict\n\nimport torch\nimport torch.distributed as dist\n\nimport mmcv\nfrom ..hook import HOOKS\nfrom .base import LoggerHook\n\n\n@HOOKS.register_module\nclass TextLoggerHook(LoggerHook):\n\n    def __init__(self, interval=10, ignore_last=True, reset_flag=False):\n        super(TextLoggerHook, self).__init__(interval, ignore_last, reset_flag)\n        self.time_sec_tot = 0\n\n    def before_run(self, runner):\n        super(TextLoggerHook, self).before_run(runner)\n        self.start_iter = runner.iter\n        self.json_log_path = osp.join(runner.work_dir,\n                                      f'{runner.timestamp}.log.json')\n        if runner.meta is not None:\n            self._dump_log(runner.meta, runner)\n\n    def _get_max_memory(self, runner):\n        mem = torch.cuda.max_memory_allocated()\n        mem_mb = torch.tensor([mem / (1024 * 1024)],\n                              dtype=torch.int,\n                              device=torch.device('cuda'))\n        if runner.world_size > 1:\n            dist.reduce(mem_mb, 0, op=dist.ReduceOp.MAX)\n        return mem_mb.item()\n\n    def _log_info(self, log_dict, runner):\n        if runner.mode == 'train':\n            log_str = f'Epoch [{log_dict[\"epoch\"]}]' \\\n                      f'[{log_dict[\"iter\"]}/{len(runner.data_loader)}]\\t' \\\n                      f'lr: {log_dict[\"lr\"]:.5f}, '\n            if 'time' in log_dict.keys():\n                self.time_sec_tot += (log_dict['time'] * self.interval)\n                time_sec_avg = self.time_sec_tot / (\n                    runner.iter - self.start_iter + 1)\n                eta_sec = time_sec_avg * (runner.max_iters - runner.iter - 1)\n                eta_str = str(datetime.timedelta(seconds=int(eta_sec)))\n                log_str += f'eta: {eta_str}, '\n                log_str += f'time: {log_dict[\"time\"]:.3f}, ' \\\n                           f'data_time: {log_dict[\"data_time\"]:.3f}, '\n                # statistic memory\n                if torch.cuda.is_available():\n                    log_str += f'memory: {log_dict[\"memory\"]}, '\n        else:\n            log_str = 'Epoch({log_dict[\"mode\"]}) ' \\\n                      f'[{log_dict[\"epoch\"] - 1}][{log_dict[\"iter\"]}]\\t'\n        log_items = []\n        for name, val in log_dict.items():\n            # TODO: resolve this hack\n            # these items have been in log_str\n            if name in [\n                    'mode', 'Epoch', 'iter', 'lr', 'time', 'data_time',\n                    'memory', 'epoch'\n            ]:\n                continue\n            if isinstance(val, float):\n                val = f'{val:.4f}'\n            log_items.append(f'{name}: {val}')\n        log_str += ', '.join(log_items)\n        runner.logger.info(log_str)\n\n    def _dump_log(self, log_dict, runner):\n        # dump log in json format\n        json_log = OrderedDict()\n        for k, v in log_dict.items():\n            json_log[k] = self._round_float(v)\n        # only append log at last line\n        if runner.rank == 0:\n            with open(self.json_log_path, 'a+') as f:\n                mmcv.dump(json_log, f, file_format='json')\n                f.write('\\n')\n\n    def _round_float(self, items):\n        if isinstance(items, list):\n            return [self._round_float(item) for item in items]\n        elif isinstance(items, float):\n            return round(items, 5)\n        else:\n            return items\n\n    def log(self, runner):\n        log_dict = OrderedDict()\n        # training mode if the output contains the key \"time\"\n        mode = 'train' if 'time' in runner.log_buffer.output else 'val'\n        log_dict['mode'] = mode\n        log_dict['epoch'] = runner.epoch + 1\n        log_dict['iter'] = runner.inner_iter + 1\n        # only record lr of the first param group\n        log_dict['lr'] = runner.current_lr()[0]\n        if mode == 'train':\n            log_dict['time'] = runner.log_buffer.output['time']\n            log_dict['data_time'] = runner.log_buffer.output['data_time']\n\n            # statistic memory\n            if torch.cuda.is_available():\n                log_dict['memory'] = self._get_max_memory(runner)\n        for name, val in runner.log_buffer.output.items():\n            if name in ['time', 'data_time']:\n                continue\n            log_dict[name] = val\n\n        self._log_info(log_dict, runner)\n        self._dump_log(log_dict, runner)\n", "path": "mmcv/runner/hooks/logger/text.py"}]}