| 442 | raise ke |
| 443 | |
| 444 | def decref(self, c, ident): |
| 445 | if ident not in self.id_to_refcount and \ |
| 446 | ident in self.id_to_local_proxy_obj: |
| 447 | util.debug('Server DECREF skipping %r', ident) |
| 448 | return |
| 449 | |
| 450 | with self.mutex: |
| 451 | if self.id_to_refcount[ident] <= 0: |
| 452 | raise AssertionError( |
| 453 | "Id {0!s} ({1!r}) has refcount {2:n}, not 1+".format( |
| 454 | ident, self.id_to_obj[ident], |
| 455 | self.id_to_refcount[ident])) |
| 456 | self.id_to_refcount[ident] -= 1 |
| 457 | if self.id_to_refcount[ident] == 0: |
| 458 | del self.id_to_refcount[ident] |
| 459 | |
| 460 | if ident not in self.id_to_refcount: |
| 461 | # Two-step process in case the object turns out to contain other |
| 462 | # proxy objects (e.g. a managed list of managed lists). |
| 463 | # Otherwise, deleting self.id_to_obj[ident] would trigger the |
| 464 | # deleting of the stored value (another managed object) which would |
| 465 | # in turn attempt to acquire the mutex that is already held here. |
| 466 | self.id_to_obj[ident] = (None, (), None) # thread-safe |
| 467 | util.debug('disposing of obj with id %r', ident) |
| 468 | with self.mutex: |
| 469 | del self.id_to_obj[ident] |
| 470 | |
| 471 | |
| 472 | # |