1
0
mirror of https://github.com/apple/foundationdb.git synced 2025-06-01 10:45:56 +08:00

Python now blocks on a future in Python rather than in native code to preserve Python's signal handling functionality. In particular, this means that ctrl-c will work in the REPL.

This commit is contained in:
A.J. Beamon 2019-02-08 13:51:01 -08:00
parent 4c0481da40
commit 8960670694

@ -30,6 +30,7 @@ import datetime
import platform
import os
import sys
import multiprocessing
from fdb import six
@ -38,6 +39,8 @@ _network_thread_reentrant_lock = threading.RLock()
_open_file = open
_thread_local_storage = threading.local()
import weakref
@ -593,7 +596,20 @@ class Future(_FDBBase):
return bool(self.capi.fdb_future_is_ready(self.fpointer))
def block_until_ready(self):
self.capi.fdb_future_block_until_ready(self.fpointer)
# Checking readiness is faster than using the callback, so it saves us time if we are already
# ready. It also doesn't add much to the cost of this function
if not self.is_ready():
# Blocking in the native client from the main thread prevents Python from handling signals.
# To avoid that behavior, we implement the blocking in Python using semaphores and on_ready.
# Using a Semaphore is faster than an Event, and we create only one per thread to avoid the
# cost of creating one every time.
semaphore = getattr(_thread_local_storage, 'future_block_semaphore', None)
if semaphore is None:
semaphore = multiprocessing.Semaphore(0)
_thread_local_storage.future_block_semaphore = semaphore
self.on_ready(lambda self: semaphore.release())
semaphore.acquire()
def on_ready(self, callback):
def cb_and_delref(ignore):