Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -363,6 +363,7 @@ answer newbie questions, and generally made Django that much better: Ben Slavin <benjamin.slavin@gmail.com> sloonz <simon.lipp@insa-lyon.fr> SmileyChris <smileychris@gmail.com> Warren Smith <warren@wandrsmith.net> smurf@smurf.noris.de Vsevolod Solovyov sopel Loading django/contrib/sessions/backends/file.py +40 −8 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ import tempfile from django.conf import settings from django.contrib.sessions.backends.base import SessionBase, CreateError from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured from django.core.files import locks IO_LOCK_SUFFIX = "_iolock" class SessionStore(SessionBase): """ Loading Loading @@ -42,8 +44,22 @@ class SessionStore(SessionBase): return os.path.join(self.storage_path, self.file_prefix + session_key) def _key_to_io_lock_file(self, session_key=None): """ Get the I/O lock file associated with this session key. """ return self._key_to_file(session_key) + IO_LOCK_SUFFIX def load(self): session_data = {} try: # Open and acquire a shared lock on the I/O lock file before # attempting to read the session file. This makes us wait to read # the session file until another thread or process is finished # writing it. lock_path = self._key_to_io_lock_file() io_lock_file = open(lock_path, "rb") locks.lock(io_lock_file, locks.LOCK_SH) try: session_file = open(self._key_to_file(), "rb") try: Loading @@ -53,6 +69,10 @@ class SessionStore(SessionBase): self.create() finally: session_file.close() finally: locks.unlock(io_lock_file) io_lock_file.close() os.unlink(lock_path) except IOError: pass return session_data Loading @@ -75,12 +95,24 @@ class SessionStore(SessionBase): # Because this may trigger a load from storage, we must do it before # truncating the file to save. session_data = self._get_session(no_load=must_create) try: # Open and acquire an exclusive lock on the I/O lock file before # attempting to write the session file. This makes other threads # or processes wait to read or write the session file until we are # finished writing it. lock_path = self._key_to_io_lock_file() io_lock_file = open(lock_path, "wb") locks.lock(io_lock_file, locks.LOCK_EX) try: fd = os.open(self._key_to_file(self.session_key), flags) try: os.write(fd, self.encode(session_data)) finally: os.close(fd) finally: locks.unlock(io_lock_file) io_lock_file.close() os.unlink(lock_path) except OSError, e: if must_create and e.errno == errno.EEXIST: raise CreateError Loading Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -363,6 +363,7 @@ answer newbie questions, and generally made Django that much better: Ben Slavin <benjamin.slavin@gmail.com> sloonz <simon.lipp@insa-lyon.fr> SmileyChris <smileychris@gmail.com> Warren Smith <warren@wandrsmith.net> smurf@smurf.noris.de Vsevolod Solovyov sopel Loading
django/contrib/sessions/backends/file.py +40 −8 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ import tempfile from django.conf import settings from django.contrib.sessions.backends.base import SessionBase, CreateError from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured from django.core.files import locks IO_LOCK_SUFFIX = "_iolock" class SessionStore(SessionBase): """ Loading Loading @@ -42,8 +44,22 @@ class SessionStore(SessionBase): return os.path.join(self.storage_path, self.file_prefix + session_key) def _key_to_io_lock_file(self, session_key=None): """ Get the I/O lock file associated with this session key. """ return self._key_to_file(session_key) + IO_LOCK_SUFFIX def load(self): session_data = {} try: # Open and acquire a shared lock on the I/O lock file before # attempting to read the session file. This makes us wait to read # the session file until another thread or process is finished # writing it. lock_path = self._key_to_io_lock_file() io_lock_file = open(lock_path, "rb") locks.lock(io_lock_file, locks.LOCK_SH) try: session_file = open(self._key_to_file(), "rb") try: Loading @@ -53,6 +69,10 @@ class SessionStore(SessionBase): self.create() finally: session_file.close() finally: locks.unlock(io_lock_file) io_lock_file.close() os.unlink(lock_path) except IOError: pass return session_data Loading @@ -75,12 +95,24 @@ class SessionStore(SessionBase): # Because this may trigger a load from storage, we must do it before # truncating the file to save. session_data = self._get_session(no_load=must_create) try: # Open and acquire an exclusive lock on the I/O lock file before # attempting to write the session file. This makes other threads # or processes wait to read or write the session file until we are # finished writing it. lock_path = self._key_to_io_lock_file() io_lock_file = open(lock_path, "wb") locks.lock(io_lock_file, locks.LOCK_EX) try: fd = os.open(self._key_to_file(self.session_key), flags) try: os.write(fd, self.encode(session_data)) finally: os.close(fd) finally: locks.unlock(io_lock_file) io_lock_file.close() os.unlink(lock_path) except OSError, e: if must_create and e.errno == errno.EEXIST: raise CreateError Loading