Changeset 391 for python/trunk/Lib/multiprocessing/heap.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/multiprocessing/heap.py
r2 r391 4 4 # multiprocessing/heap.py 5 5 # 6 # Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt 6 # Copyright (c) 2006-2008, R Oudkerk 7 # All rights reserved. 8 # 9 # Redistribution and use in source and binary forms, with or without 10 # modification, are permitted provided that the following conditions 11 # are met: 12 # 13 # 1. Redistributions of source code must retain the above copyright 14 # notice, this list of conditions and the following disclaimer. 15 # 2. Redistributions in binary form must reproduce the above copyright 16 # notice, this list of conditions and the following disclaimer in the 17 # documentation and/or other materials provided with the distribution. 18 # 3. Neither the name of author nor the names of any contributors may be 19 # used to endorse or promote products derived from this software 20 # without specific prior written permission. 21 # 22 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 23 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 # SUCH DAMAGE. 7 33 # 8 34 … … 27 53 if sys.platform == 'win32': 28 54 29 from ._multiprocessing import win3255 from _multiprocessing import win32 30 56 31 57 class Arena(object): … … 76 102 self._allocated_blocks = set() 77 103 self._arenas = [] 104 # list of pending blocks to free - see free() comment below 105 self._pending_free_blocks = [] 78 106 79 107 @staticmethod … … 150 178 return start, stop 151 179 180 def _free_pending_blocks(self): 181 # Free all the blocks in the pending list - called with the lock held. 182 while True: 183 try: 184 block = self._pending_free_blocks.pop() 185 except IndexError: 186 break 187 self._allocated_blocks.remove(block) 188 self._free(block) 189 152 190 def free(self, block): 153 191 # free a block returned by malloc() 192 # Since free() can be called asynchronously by the GC, it could happen 193 # that it's called while self._lock is held: in that case, 194 # self._lock.acquire() would deadlock (issue #12352). To avoid that, a 195 # trylock is used instead, and if the lock can't be acquired 196 # immediately, the block is added to a list of blocks to be freed 197 # synchronously sometimes later from malloc() or free(), by calling 198 # _free_pending_blocks() (appending and retrieving from a list is not 199 # strictly thread-safe but under cPython it's atomic thanks to the GIL). 154 200 assert os.getpid() == self._lastpid 155 self._lock.acquire() 156 try: 157 self._allocated_blocks.remove(block) 158 self._free(block) 159 finally: 160 self._lock.release() 201 if not self._lock.acquire(False): 202 # can't acquire the lock right now, add the block to the list of 203 # pending blocks to free 204 self._pending_free_blocks.append(block) 205 else: 206 # we hold the lock 207 try: 208 self._free_pending_blocks() 209 self._allocated_blocks.remove(block) 210 self._free(block) 211 finally: 212 self._lock.release() 161 213 162 214 def malloc(self, size): … … 166 218 self.__init__() # reinitialize after fork 167 219 self._lock.acquire() 220 self._free_pending_blocks() 168 221 try: 169 222 size = self._roundup(max(size,1), self._alignment)
Note:
See TracChangeset
for help on using the changeset viewer.