def _needs_document_lock(func):
 @gen.coroutine
 def _needs_document_lock_wrapper(self, *args, **kwargs):
  self.block_expiration()
  try:
   with (yield self._lock.acquire()):
    if (self._pending_writes is not None):
     raise RuntimeError(('internal class invariant violated: _pending_writes ' + 'should be None if lock is not held'))
    self._pending_writes = []
    try:
     result = (yield yield_for_all_futures(func(self, *args, **kwargs)))
    finally:
     pending_writes = self._pending_writes
     self._pending_writes = None
    for p in pending_writes:
     (yield p)
   raise gen.Return(result)
  finally:
   self.unblock_expiration()
 return _needs_document_lock_wrapper

def _needs_document_lock ( func ) : @ gen . coroutine def _needs_document_lock_wrapper ( self , * args , ** kwargs ) : self . block_expiration ( ) try : with ( yield self . _lock . acquire ( ) ) : if ( self . _pending_writes is not None ) : raise RuntimeError ( ( 'internal class invariant violated: _pending_writes ' + 'should be None if lock is not held' ) ) self . _pending_writes = [ ] try : result = ( yield yield_for_all_futures ( func ( self , * args , ** kwargs ) ) ) finally : pending_writes = self . _pending_writes self . _pending_writes = None for p in pending_writes : ( yield p ) raise gen . Return ( result ) finally : self . unblock_expiration ( ) return _needs_document_lock_wrapper
decorator that adds the necessary locking and post-processing to manipulate the sessions document .