Reverted #8688 for now, since it merely introduced different bugs, rather than

fixing the problem. We have a plan B (and plan C, if needed), so this will be
fixed in a different way.

Refs #8616.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8707 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-08-29 17:32:21 +00:00
parent c113133dad
commit 3717e3bba3
2 changed files with 8 additions and 41 deletions

View File

@ -363,7 +363,6 @@ answer newbie questions, and generally made Django that much better:
Ben Slavin <benjamin.slavin@gmail.com> Ben Slavin <benjamin.slavin@gmail.com>
sloonz <simon.lipp@insa-lyon.fr> sloonz <simon.lipp@insa-lyon.fr>
SmileyChris <smileychris@gmail.com> SmileyChris <smileychris@gmail.com>
Warren Smith <warren@wandrsmith.net>
smurf@smurf.noris.de smurf@smurf.noris.de
Vsevolod Solovyov Vsevolod Solovyov
sopel sopel

View File

@ -5,9 +5,7 @@ import tempfile
from django.conf import settings from django.conf import settings
from django.contrib.sessions.backends.base import SessionBase, CreateError from django.contrib.sessions.backends.base import SessionBase, CreateError
from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured
from django.core.files import locks
IO_LOCK_SUFFIX = "_iolock"
class SessionStore(SessionBase): class SessionStore(SessionBase):
""" """
@ -44,35 +42,17 @@ class SessionStore(SessionBase):
return os.path.join(self.storage_path, self.file_prefix + session_key) 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): def load(self):
session_data = {} session_data = {}
try: try:
# Open and acquire a shared lock on the I/O lock file before session_file = open(self._key_to_file(), "rb")
# 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: try:
session_file = open(self._key_to_file(), "rb")
try: try:
try: session_data = self.decode(session_file.read())
session_data = self.decode(session_file.read()) except (EOFError, SuspiciousOperation):
except (EOFError, SuspiciousOperation): self.create()
self.create()
finally:
session_file.close()
finally: finally:
locks.unlock(io_lock_file) session_file.close()
io_lock_file.close()
os.unlink(lock_path)
except IOError: except IOError:
pass pass
return session_data return session_data
@ -96,23 +76,11 @@ class SessionStore(SessionBase):
# truncating the file to save. # truncating the file to save.
session_data = self._get_session(no_load=must_create) session_data = self._get_session(no_load=must_create)
try: try:
# Open and acquire an exclusive lock on the I/O lock file before fd = os.open(self._key_to_file(self.session_key), flags)
# 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: try:
fd = os.open(self._key_to_file(self.session_key), flags) os.write(fd, self.encode(session_data))
try:
os.write(fd, self.encode(session_data))
finally:
os.close(fd)
finally: finally:
locks.unlock(io_lock_file) os.close(fd)
io_lock_file.close()
os.unlink(lock_path)
except OSError, e: except OSError, e:
if must_create and e.errno == errno.EEXIST: if must_create and e.errno == errno.EEXIST:
raise CreateError raise CreateError