summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/utils/autoreload.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py
index ba98530f1b..6816403cc7 100644
--- a/django/utils/autoreload.py
+++ b/django/utils/autoreload.py
@@ -65,6 +65,16 @@ try:
except ImportError:
pass
+try:
+ import select
+ select.kevent, select.kqueue
+ USE_KQUEUE = True
+
+ import resource
+ NOFILES_SOFT, NOFILES_HARD = resource.getrlimit(resource.RLIMIT_NOFILE)
+except AttributeError:
+ USE_KQUEUE = False
+
RUN_RELOADER = True
_mtimes = {}
@@ -119,6 +129,31 @@ def inotify_code_changed():
# If we are here the code must have changed.
return True
+def kqueue_code_changed():
+ """
+ Checks for changed code using kqueue. After being called
+ it blocks until a change event has been fired.
+ """
+ # Maximum number of open file descriptors is typically too low (256).
+ filenames = list(gen_filenames())
+ resource.setrlimit(resource.RLIMIT_NOFILE,
+ (NOFILES_SOFT + len(filenames), NOFILES_HARD))
+
+ kqueue = select.kqueue()
+ fds = [open(filename) for filename in filenames]
+
+ _filter = select.KQ_FILTER_VNODE
+ flags = select.KQ_EV_ADD
+ fflags = select.KQ_NOTE_DELETE | select.KQ_NOTE_WRITE | select.KQ_NOTE_RENAME
+ kevents = [select.kevent(fd, _filter, flags, fflags) for fd in fds]
+ kqueue.control(kevents, 1)
+
+ for fd in fds:
+ fd.close()
+ kqueue.close()
+
+ return True
+
def code_changed():
global _mtimes, _win
for filename in gen_filenames():
@@ -178,6 +213,8 @@ def reloader_thread():
ensure_echo_on()
if USE_INOTIFY:
fn = inotify_code_changed
+ elif USE_KQUEUE:
+ fn = kqueue_code_changed
else:
fn = code_changed
while RUN_RELOADER: