Index: django/db/models/serializer.py
===================================================================
--- django/db/models/serializer.py	(revisione 0)
+++ django/db/models/serializer.py	(revisione 0)
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+# Author: Claudio Marinozzi (alias PyMan)
+
+from threading import RLock
+
+class Serializer :
+    
+    def __init__(self) :
+        self.rc = 0
+        self.lock = RLock()
+        
+    def acquire(self):
+        self.lock.acquire()
+        self.rc += 1
+        
+    def release(self):
+        self.rc -= 1
+        self.lock.release()
+
+__serializer = Serializer()
+
+#TODO: maybe it's useful the use of a new setting parameter that if setted to True then makes the use of the
+#Serialized object (multithreaded scenario), False otherwise (single threaded scenario)
+ 
+#NOTE: Now the Serializer object it's useless...it could be just used the RLock object itself.
+
+def mutex(func):
+    def decorator(*args, **kwargs):
+        __serializer.acquire()
+        try : 
+            res = func(*args, **kwargs)
+        except :
+            __serializer.release()
+            raise
+        __serializer.release()
+        return res
+    return decorator
\ Nessun a-capo alla fine del file
Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py	(revisione 6431)
+++ django/db/models/base.py	(copia locale)
@@ -19,6 +19,8 @@
 import sys
 import os
 
+from django.db.models.serializer import mutex
+
 class ModelBase(type):
     "Metaclass for all models"
     def __new__(cls, name, bases, attrs):
@@ -206,6 +208,7 @@
 
     _prepare = classmethod(_prepare)
 
+    @mutex
     def save(self, raw=False):
         dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
 
@@ -319,6 +322,7 @@
                 for sub_obj in getattr(self, rel_opts_name).all():
                     sub_obj._collect_sub_objects(seen_objs)
 
+    @mutex
     def delete(self):
         assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
 
Index: django/db/models/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revisione 6431)
+++ django/db/models/fields/related.py	(copia locale)
@@ -11,6 +11,8 @@
 from django import newforms as forms
 from django.dispatch import dispatcher
 
+from django.db.models.serializer import mutex
+
 try:
     set
 except NameError:
@@ -214,12 +216,14 @@
             def get_query_set(self):
                 return superclass.get_query_set(self).filter(**(self.core_filters))
 
+            @mutex
             def add(self, *objs):
                 for obj in objs:
                     setattr(obj, rel_field.name, instance)
                     obj.save()
             add.alters_data = True
 
+            @mutex
             def create(self, **kwargs):
                 new_obj = self.model(**kwargs)
                 self.add(new_obj)
@@ -228,6 +232,7 @@
 
             # remove() and clear() are only provided if the ForeignKey can have a value of null.
             if rel_field.null:
+                @mutex
                 def remove(self, *objs):
                     val = getattr(instance, rel_field.rel.get_related_field().attname)
                     for obj in objs:
@@ -239,6 +244,7 @@
                             raise rel_field.rel.to.DoesNotExist, "%r is not related to %r." % (obj, instance)
                 remove.alters_data = True
 
+                @mutex
                 def clear(self):
                     for obj in self.all():
                         setattr(obj, rel_field.name, None)
@@ -283,6 +289,7 @@
         def get_query_set(self):
             return superclass.get_query_set(self).filter(**(self.core_filters))
 
+        @mutex
         def add(self, *objs):
             self._add_items(self.source_col_name, self.target_col_name, *objs)
 
@@ -291,6 +298,7 @@
                 self._add_items(self.target_col_name, self.source_col_name, *objs)
         add.alters_data = True
 
+        @mutex
         def remove(self, *objs):
             self._remove_items(self.source_col_name, self.target_col_name, *objs)
 
@@ -299,6 +307,7 @@
                 self._remove_items(self.target_col_name, self.source_col_name, *objs)
         remove.alters_data = True
 
+        @mutex
         def clear(self):
             self._clear_items(self.source_col_name)
 
@@ -307,6 +316,7 @@
                 self._clear_items(self.target_col_name)
         clear.alters_data = True
 
+        @mutex
         def create(self, **kwargs):
             new_obj = self.model(**kwargs)
             new_obj.save()
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revisione 6431)
+++ django/db/models/query.py	(copia locale)
@@ -10,6 +10,8 @@
 import operator
 import re
 
+from django.db.models.serializer import mutex
+
 try:
     set
 except NameError:
@@ -264,6 +266,7 @@
         assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs)
         return obj_list[0]
 
+    @mutex
     def create(self, **kwargs):
         """
         Create a new object with the given kwargs, saving it to the database
@@ -273,6 +276,7 @@
         obj.save()
         return obj
 
+    @mutex
     def get_or_create(self, **kwargs):
         """
         Looks up an object with the given kwargs, creating one if necessary.
@@ -318,6 +322,7 @@
         qs._params.extend(id_list)
         return dict([(obj._get_pk_val(), obj) for obj in qs.iterator()])
 
+    @mutex
     def delete(self):
         """
         Deletes the records in the current QuerySet.

